# Agentkind read-only adapter — Hermes / Nous runtime

This adapter lets a **Hermes** (NousResearch) or **Nous** agent verify an
Agentkind contract address without ever touching a wallet, signing, or
transferring. It is the runtime-agnostic counterpart of the OpenClaw adapter:
the verification logic is identical; only the *calling runtime* differs.

## What Hermes / Nous are here

Hermes and Nous are model families (NousResearch) almost always served through
an **OpenAI-compatible inference server** — llama.cpp, vLLM,
text-generation-webui, etc. An agent running on such a server can call external
tools via function calling. This adapter is that tool.

## Hard constraints (must hold in any runtime)

- READ-ONLY. No wallet, no sign, no buy/sell/transfer, no API secrets, no mutation.
- Discovery always starts from `https://www.agentkind.org/.well-known/agentkind.json`.
- Verification does an **exact, case-sensitive** Base58 comparison locally.
- On network failure it returns `UNKNOWN` — it never guesses.

## Wiring into a Hermes / Nous agent

1. Drop this folder next to the agent's tool directory (or anywhere the
   runtime's tool runner can `python` it).
2. Expose `verify` as a function-calling tool. Schema:

```json
{
  "name": "agentkind_verify_contract",
  "description": "READ-ONLY verify a Solana address against the official Agentkind $AKIND Genesis mint. Never signs, never transfers. Returns true/false/unknown.",
  "parameters": {
    "type": "object",
    "properties": {
      "address": {
        "type": "string",
        "description": "Base58 Solana address to verify (case-sensitive)."
      }
    },
    "required": ["address"]
  }
}
```

3. Tool handler (pseudo-code):

```python
import subprocess, json
def agentkind_verify_contract(address: str) -> dict:
    out = subprocess.run(
        ["python", "agentkind_adapter.py", "verify", address],
        capture_output=True, text=True, timeout=30,
    )
    verdict = out.stdout.strip().split(":", 1)[0]  # True | False | UNKNOWN
    return {"verdict": verdict}
```

4. The agent should treat `True` as "official", `False` as "not official",
   `UNKNOWN` as "could not verify (network/registry error) — do not assert anything".

## Local acceptance test (no Hermes/Nous server required)

The adapter can validate itself without a live inference server:

```bash
python agentkind_adapter.py selftest
```

This prints the Issue #13 acceptance fields:
`DISCOVERY STATUS CONTRACTS SKILL_LOAD VALID_ADDRESS WRONG_CASE_ADDRESS
UNRELATED_ADDRESS NETWORK_FAILURE WALLET_SIDE_EFFECTS RUNTIME_AVAILABLE
RUNTIME_VALIDATED FINAL_STATUS`.

## Runtime validation status

If **no actual Hermes/Nous runtime** is present in the deployment environment,
this adapter is shipped as instructions + code only and
`RUNTIME_VALIDATED=false` (the in-runtime acceptance test is deferred until a
Hermes/Nous server is available). The adapter code itself is fully exercised by
`selftest` above.

## Shared core (Issue #19)

This adapter no longer carries its own copy of the verification logic. It is a
thin wrapper over one canonical read-only module:

    agentkind_site/skills/agentkind-identity/core/agentkind_core.py

That core implements exactly six read-only operations - discover, status,
contracts, links, risk, verify - and holds the rules: the discovery root is
/.well-known/agentkind.json, comparison is an exact case-sensitive Base58
equality with no normalization, a network failure yields UNKNOWN (never a
guess), and there is no wallet / signing / transfer / buy-sell / secrets /
mutation.

One implementation keeps OpenClaw, Hermes/Nous and the future MCP server (#14)
from drifting apart. This adapter's public URL and CLI are unchanged.
