{"type":"text/markdown","content":"# Verify Before Execute — HOLA recipes for verifiers\n\n**MCP resource URI:** `doc:reference:verify-hola-recipes`\n\nCopy-paste integration for **demand-side verifiers** — agents and services that receive HOLA lines or collaboration envelopes and must decide whether to run tools, share secrets, or execute `task.payload`.\n\n**Norm:** **Verify before execute.** Never run delegated work until HOLA verification succeeds. Publish your canonical **`tokenId`** on channels you control so peers can confirm they are talking to you, not a look-alike Passport.\n\n**Peer HOLA is offline.** Agent-to-agent HOLA happens **entirely outside** any central broker — directly between peers on whatever channel already carries the conversation (OpenClaw inter-agent messaging, email, webhooks, game private side-channels, etc.). The game server and IdentyClaw HTTP API do **not** broker HOLA on the wire. Each receiving peer **verifies independently**, using **IdentyClaw API** (`POST /api/identity/verify`) or **direct NEAR RPC** (e.g. `@rodit/rodit-auth-be`) — whichever that peer chooses.\n\n**Related:** [`identity-verification-policy.md`](identity-verification-policy.md), [`collaboration-envelope.md`](collaboration-envelope.md), [`hola-howto.md`](hola-howto.md), [`finding-agents.md` §5](finding-agents.md#5-guard-against-impersonation).\n\nRunnable examples (optional API verify path): [`examples/verify-before-execute/`](../examples/verify-before-execute/).\n\n---\n\n## Why verifiers are near-zero cost\n\n| Party | One-time cost | Per-peer cost |\n| --- | --- | --- |\n| **Passport holder (sender)** | Mint Passport + lifecycle fee | Fresh HOLA nonce (~5 min TTL) per handshake; sign on agent host |\n| **Verifier (peer agent)** | Passport + chosen verify stack | **Independent full validation** per inbound HOLA — IdentyClaw API or direct RPC, peer's choice |\n\nYou do **not** route HOLA exchange through a game or identity broker. You do **not** register each peer in advance. Peers exchange HOLA on their existing channel; each peer verifies by its chosen path.\n\n**Two verify paths** (same proof bar — **peer chooses either**):\n\n| Path | When |\n| --- | --- |\n| **Via IdentyClaw HTTP API** | `POST /api/identity/verify` when the peer prefers the hosted helper (public; optional JWT) |\n| **Direct NEAR RPC** | `@rodit/rodit-auth-be` (or equivalent) + your chosen RPC endpoint |\n\nNeither path is required for **exchanging** HOLA. Either satisfies **verify before execute** when the full proof bar is applied. See [`identity-verification-policy.md` §1](identity-verification-policy.md#1-two-verification-paths).\n\nLocal checksum or bare Ed25519 checks alone are **not** sufficient ([`hola-agent-authentication.md` § When is a HOLA validated?](hola-agent-authentication.md#when-is-a-hola-validated)).\n\n---\n\n## Verify before execute (the rule)\n\nUse this order on **every** inbound agent message that carries work:\n\n```text\n1. Parse payload (plain HOLA string or identyclaw.collaboration.v1 envelope)\n2. **Verify HOLA independently** — IdentyClaw API or direct NEAR RPC, peer's choice (full proof bar — not checksum alone).\n3. Match peerTokenId ↔ envelope.from.tokenId (if envelope)\n4. Impersonation guard — peerTokenId matches principal's published tokenId (optional but recommended)\n5. Subagent only — POST /api/isauthorizedsigner when delegation format\n6. Execute task / grant tools — ONLY after steps 2–5 pass\n```\n\n**Language for your docs, runbooks, and agent prompts:** *\"Verify before execute — HOLA first, tools second.\"*\n\n**Publish your Passport ID:** Legitimate operators post their 12-letter `tokenId` on website, GitHub, ClawHub, or verified social. Verifiers compare verified `peerTokenId` to that canonical ID before treating the sender as that brand or human principal.\n\n---\n\n## Recipe 1 — Node.js (~20 lines, IdentyClaw API verify path)\n\n**Peer choice:** use this recipe when the verifying peer prefers **`POST /api/identity/verify`**. For **direct NEAR RPC**, see [`identity-verification-policy.md` §1](identity-verification-policy.md#1-two-verification-paths) and `@rodit/rodit-auth-be`. HOLA is still exchanged offline P2P — this HTTP call is only the verifier's validation step.\n\nRequires Node 18+ (`fetch` built in). JWT is optional — pass when logged in for `RECIPIENT_MISMATCH` handling.\n\n```javascript\nconst BASE = process.env.IDENTYCLAW_BASE_URL || \"https://api.identyclaw.com\";\n\nasync function verifyHola(hola, { jwt, expectedRecipient } = {}) {\n  const body = { hola };\n  if (expectedRecipient) body.expectedRecipient = expectedRecipient;\n  const headers = { \"Content-Type\": \"application/json\" };\n  if (jwt) headers.Authorization = `Bearer ${jwt}`;\n  const res = await fetch(`${BASE}/api/identity/verify`, {\n    method: \"POST\",\n    headers,\n    body: JSON.stringify(body),\n  });\n  const result = await res.json();\n  if (!res.ok) throw new Error(result.message || `HTTP ${res.status}`);\n  return result;\n}\n\nfunction verifyBeforeExecute(result, { fromTokenId, canonicalPublishedId } = {}) {\n  if (!result.verified) throw new Error(`HOLA rejected: ${(result.failureReasons || []).join(\", \")}`);\n  if (fromTokenId && result.peerTokenId !== fromTokenId) throw new Error(\"from.tokenId mismatch\");\n  if (canonicalPublishedId && result.peerTokenId !== canonicalPublishedId) throw new Error(\"impersonation guard failed\");\n  return result;\n}\n\n// Usage:\n// const r = await verifyHola(inboundHola, { jwt: process.env.IDENTYCLAW_JWT, expectedRecipient: \"yourtokenid12\" });\n// verifyBeforeExecute(r, { fromTokenId: envelope.from.tokenId, canonicalPublishedId: \"bkbvehbdcrgm\" });\n// → now safe to run task.payload\n```\n\nFull script: [`examples/verify-before-execute/verify-hola.mjs`](../examples/verify-before-execute/verify-hola.mjs).\n\n---\n\n## Recipe 2 — Python (~20 lines)\n\n```python\nimport os, json, urllib.request\n\nBASE = os.environ.get(\"IDENTYCLAW_BASE_URL\", \"https://api.identyclaw.com\")\n\ndef verify_hola(hola: str, *, jwt: str | None = None, expected_recipient: str | None = None) -> dict:\n    body = {\"hola\": hola}\n    if expected_recipient:\n        body[\"expectedRecipient\"] = expected_recipient\n    headers = {\"Content-Type\": \"application/json\"}\n    if jwt:\n        headers[\"Authorization\"] = f\"Bearer {jwt}\"\n    req = urllib.request.Request(\n        f\"{BASE}/api/identity/verify\",\n        data=json.dumps(body).encode(),\n        headers=headers,\n        method=\"POST\",\n    )\n    with urllib.request.urlopen(req) as resp:\n        return json.loads(resp.read())\n\ndef verify_before_execute(result: dict, *, from_token_id: str | None = None, canonical_id: str | None = None) -> dict:\n    if not result.get(\"verified\"):\n        raise RuntimeError(\"HOLA rejected: \" + \", \".join(result.get(\"failureReasons\") or []))\n    pid = result.get(\"peerTokenId\")\n    if from_token_id and pid != from_token_id:\n        raise RuntimeError(\"from.tokenId mismatch\")\n    if canonical_id and pid != canonical_id:\n        raise RuntimeError(\"impersonation guard failed\")\n    return result\n```\n\n---\n\n## Recipe 3 — Bash (~15 lines)\n\nAssumes `JWT` is set when calling protected follow-ups ([`skills.md` §1](skills.md#1-login-get-jwt)).\n\n```bash\nBASE=\"${IDENTYCLAW_BASE_URL:-https://api.identyclaw.com}\"\nINBOUND_HOLA='HOLA/MUNDO/...'   # exact string from peer\n\nVERIFY=$(curl -sS -X POST \"$BASE/api/identity/verify\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$(jq -n --arg h \"$INBOUND_HOLA\" '{hola:$h}')\")\n\nVERIFIED=$(echo \"$VERIFY\" | jq -r '.verified')\nPEER=$(echo \"$VERIFY\" | jq -r '.peerTokenId')\n\nif [ \"$VERIFIED\" != \"true\" ]; then\n  echo \"verify before execute: BLOCKED\" >&2\n  echo \"$VERIFY\" | jq . >&2\n  exit 1\nfi\n\necho \"verified peer: $PEER — safe to proceed to task execution\"\n# compare $PEER to published canonical tokenId before high-assurance actions\n```\n\n---\n\n## Recipe 4 — Express middleware hook\n\nDrop before any route that executes agent-supplied tools:\n\n```javascript\nfunction requireVerifiedHola(getHolaFromReq) {\n  return async (req, res, next) => {\n    try {\n      const hola = getHolaFromReq(req);\n      if (!hola) return res.status(400).json({ error: \"missing hola\" });\n      const result = await verifyHola(hola, {\n        jwt: req.identyclawJwt,\n        expectedRecipient: req.user?.rodit_id,\n      });\n      verifyBeforeExecute(result);\n      req.verifiedPeer = result.peerTokenId;\n      next();\n    } catch (err) {\n      res.status(403).json({ error: \"verify before execute\", detail: err.message });\n    }\n  };\n}\n\n// app.post(\"/agent/run\", requireVerifiedHola((req) => req.body.hola), runToolsHandler);\n```\n\nAttach `req.identyclawJwt` from your existing session middleware when you want `RECIPIENT_MISMATCH` warnings; verify itself does not require a JWT.\n\n---\n\n## Recipe 5 — Collaboration envelope (verify before execute)\n\nWhen inbound JSON uses `identyclaw.collaboration.v1`:\n\n```javascript\nasync function verifyEnvelopeBeforeExecute(envelopeJson, { jwt, canonicalPublishedId } = {}) {\n  const envelope = typeof envelopeJson === \"string\" ? JSON.parse(envelopeJson) : envelopeJson;\n  if (envelope.schema !== \"identyclaw.collaboration.v1\") throw new Error(\"unsupported schema\");\n  const result = await verifyHola(envelope.hola, {\n    jwt,\n    expectedRecipient: envelope.to?.tokenId,\n  });\n  verifyBeforeExecute(result, {\n    fromTokenId: envelope.from?.tokenId,\n    canonicalPublishedId,\n  });\n  return { peerTokenId: result.peerTokenId, task: envelope.task };\n}\n\n// const { task } = await verifyEnvelopeBeforeExecute(rawBody, {\n//   jwt: process.env.IDENTYCLAW_JWT,\n//   canonicalPublishedId: \"bkbvehbdcrgm\",\n// });\n// await executeTask(task);  // only after verify\n```\n\nFull script: [`examples/verify-before-execute/verify-envelope.mjs`](../examples/verify-before-execute/verify-envelope.mjs). Envelope spec: [`collaboration-envelope.md`](collaboration-envelope.md).\n\n---\n\n## Recipe 6 — OpenClaw (zero custom code)\n\nInstall the plugin once on the Gateway:\n\n```bash\nopenclaw plugins install clawhub:@identyclaw/openclaw-identyclaw-plugin\n```\n\n| Step | Tool |\n| --- | --- |\n| Verify inbound HOLA | `identyclaw_verify_hola` |\n| Subagent delegation | `identyclaw_check_subagent_signer` after verify |\n| Outbound reply HOLA | `identyclaw_create_hola` (complete mutual auth on same channel) |\n\n**Agent prompt line:** *\"Verify before execute: call `identyclaw_verify_hola` on `envelope.hola` before any tool named in `task.payload`.\"*\n\nSee [`openclaw-integration-guide.md`](openclaw-integration-guide.md) and [`identyclaw-a2a-trust-skill/`](../identyclaw-a2a-trust-skill/).\n\n---\n\n## Impersonation guard (publish your tokenId)\n\nVerification proves **which Passport signed the message**, not that the Passport belongs to a particular human or brand.\n\nAfter `verified: true`:\n\n1. Load the principal's **published** `tokenId` from a channel they control (website footer, GitHub org README, ClawHub skill page).\n2. Compare to `peerTokenId` from verify.\n3. Reject high-assurance actions if they differ — even when cryptography passed.\n\n**As a Passport holder:** publish your canonical `tokenId` wherever verifiers already trust you. That makes **verify before execute** meaningful to humans, not only to other agents.\n\nDetails: [`finding-agents.md` §5](finding-agents.md#5-guard-against-impersonation).\n\n---\n\n## Quick start — direct NEAR RPC (recommended)\n\n```bash\nexport NEAR_RPC_URL=\"https://rpc.mainnet.fastnear.com\"\nexport NEAR_CONTRACT_ID=\"genaaaa-identyclaw-com.near\"\nexport IDENTYCLAW_CANONICAL_PEER_ID=\"<lemuel-gulliver-lobby-tokenId>\"\n\nnpx @rodit/verify-hola report \"HOLA/...\" --rpc\n```\n\nMonorepo thin wrapper: [`examples/verify-before-execute/verify-hola-rpc.mjs`](../examples/verify-before-execute/verify-hola-rpc.mjs) (requires `npm install @rodit/verify-hola`). Source: [discernible-io/sdk](https://github.com/discernible-io/sdk) (`verify-hola/`).\n\n## Quick start — web and API CLI\n\n| Tool | Usage |\n| --- | --- |\n| **Web** | https://verify.identyclaw.com — paste HOLA, get verify + passport profile |\n| **API CLI** | `npx @rodit/verify-hola report \"HOLA/...\"` (uses `POST /api/identity/verify`) |\n| **Concierge demo** | [Lemuel Gulliver](https://www.a2a-registry.org/agent/com.identyclaw.lemuel_gulliver) at identyclaw-concierge.identyclaw.com:7443 |\n| **Trust anchor** | `GET /api/concierge/trust-anchor` — official lobby `tokenId` when configured |\n\nSet `includeProfile: true` on `POST /api/identity/verify` for a single-call report (same data as CLI `report`).\n\n---\n\n## MCP resource\n\nAgents with MCP access: `doc:reference:verify-hola-recipes` (this document).\n\n```bash\ncurl -sS \"https://api.identyclaw.com/api/mcp/resource/doc:reference:verify-hola-recipes\"\n```\n\n---\n\n## Next steps\n\n| Goal | Document |\n| --- | --- |\n| Send outbound HOLA | [`hola-howto.md`](hola-howto.md) |\n| Normative proof bar | [`identity-verification-policy.md`](identity-verification-policy.md) |\n| Multi-agent fleets | [`multi-tenant-collaboration.md`](multi-tenant-collaboration.md) |\n| First contact flow | [`skills.md` § First contact](skills.md#first-contact-from-an-unknown-agent) |\n| API catalog | [`api-reference.md`](api-reference.md) |\n","requestId":"f61f8a7545fd83ee789bb5383b19076d"}