# Deep-Dive Analysis: hermes-vaultfire

**Repo:** `/home/user/workspace/hermes-vaultfire/`  
**Purpose:** Vaultfire Protocol KYA (Know Your Agent) trust layer integration as a Hermes AI agent skill  
**Author:** Ghostkey316  
**License:** MIT (2026)  
**Version:** 0.1.0

---

## 1. Repository Structure (All Non-Git Files)

```
hermes-vaultfire/
├── README.md                            (186 lines)
├── SKILL.md                             (210 lines)
├── LICENSE                              (22 lines — MIT, 2026)
├── .gitignore
├── scripts/
│   └── vaultfire_client.py              (1,204 lines — primary skill implementation)
└── tests/
    ├── __init__.py
    └── test_vaultfire_client.py         (488 lines — unit tests)
```

**Total non-git files:** 9 (+ pytest cache artifacts: `.pytest_cache/` with gitignore, CACHEDIR.TAG, README.md, cache data)

Notable absences:
- No `requirements.txt`, `setup.py`, `pyproject.toml`, or `setup.cfg`
- No `Makefile`
- No CI/CD configuration (no `.github/`, `.gitlab-ci.yml`, etc.)
- No `__init__.py` in `scripts/` (not a package — standalone script)
- No `skill.json` (uses YAML frontmatter in SKILL.md instead)

---

## 2. README.md Analysis

### Quality: **Good**

The README is well-structured and covers:
- Purpose / problem statement (KYA = "HTTPS of trust for AI agents")
- Feature table with all 8 commands
- Quick Start with install and verify steps
- Street Cred scoring breakdown table
- Full contract address table (16 Vaultfire + 1 USDC = 17 contracts)
- ASCII architecture diagram showing Hermes → skill → Base RPC → contracts
- Environment variable reference table
- External links to Vaultfire Protocol, Hermes Agent, and Hub

### Gaps in README:
- No step-by-step installation walkthrough — the "Install as a Hermes Skill" section is two commands, one of which (`hermes skills install vaultfire`) is marked as future ("when published to Skills Hub")
- No troubleshooting section
- No changelog
- No Python version requirement stated (though the code uses `str | None` type unions requiring Python 3.10+)
- No mention of pytest or how to run tests
- Architecture diagram lists "8 more contracts" without naming them

---

## 3. SKILL.md Analysis

### Quality: **Excellent**

This is the primary document consumed by a Hermes agent at runtime — it's a procedural guide for the LLM to follow when invoking the skill.

**YAML Frontmatter:**
```yaml
name: vaultfire
description: "Vaultfire Protocol KYA (Know Your Agent) trust layer..."
version: 0.1.0
author: Ghostkey316
license: MIT
metadata:
  hermes:
    tags: [Vaultfire, Trust, KYA, Base, Blockchain, Identity, Bonds, x402, XMTP, ERC-8004, Web3, AI-Safety]
    related_skills: [base]
```

SKILL.md covers:
- **"When to Use"** section — 11 bullet points describing trigger conditions for the skill (e.g., "User mentions 'KYA', 'Know Your Agent', 'Vaultfire'")
- **Prerequisites** — Python stdlib only, RPC endpoint, Hub API
- **Quick Reference** — all 8 command invocations with `--json` note
- **Procedure** — step-by-step for all 8 commands with bash examples
- **Pitfalls** — 6 documented gotchas (rate limits, read-only by default, 95 max score, accountability bond yield pool requirement, XMTP network availability, retry on 429)
- **Verification** — two sample commands to confirm working state

The SKILL.md serves as the primary integration mechanism with Hermes: it is read by the Hermes agent's skill loader to understand when and how to invoke `vaultfire_client.py` via subprocess.

### Gaps in SKILL.md:
- No documented error codes or expected failure modes beyond the pitfalls section
- `related_skills: [base]` references a `base` skill that is not included in this repo

---

## 4. vaultfire_client.py — Full Technical Analysis

### Overview
1,204 lines of pure Python 3.10+ (standard library only: `argparse`, `hashlib`, `json`, `os`, `sys`, `time`, `urllib`). No third-party dependencies. Functions as a CLI tool invoked by the Hermes skill system via subprocess.

### Architecture
The script is a **read-only on-chain query client** that:
1. Resolves a working Base RPC endpoint (with fallbacks)
2. Constructs raw ABI-encoded `eth_call` payloads manually (no `web3.py`)
3. Decodes raw hex results (bool, uint256, string)
4. Presents formatted output (human-readable or JSON)

---

### 4.1 Configuration Constants

| Constant | Value | Notes |
|----------|-------|-------|
| `CHAIN_ID` | `8453` | Base Mainnet |
| `RPC_TIMEOUT` | `8` seconds | Per request |
| `RPC_RETRIES` | `2` | On HTTP 429 |
| `BACKOFF_BASE` | `1.5` seconds | Exponential: delay = 1.5 × attempt |
| `BASE_SCAN` | `https://basescan.org/address` | For output links |

**RPC Fallback Chain:**
```python
_RPC_FALLBACKS = [
    "https://mainnet.base.org",
    "https://1rpc.io/base",
    "https://base-rpc.publicnode.com",
    "https://base.meowrpc.com",
]
```
All are public, rate-limited endpoints. The active RPC is cached globally (`_active_rpc`). On any connection error, the cache is cleared and fallbacks are tried in order.

---

### 4.2 Contract Addresses (All 17, Base Mainnet Chain ID 8453)

| Contract Name | Address | README Status |
|---------------|---------|---------------|
| ERC8004IdentityRegistry | `0x35978DB675576598F0781dA2133E94cdCf4858bC` | LIVE |
| ERC8004ReputationRegistry | `0xdB54B8925664816187646174bdBb6Ac658A55a5F` | LIVE |
| VaultfireNameService | `0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25` | LIVE |
| AIPartnershipBondsV2 | `0xC574CF2a09B0B470933f0c6a3ef422e3fb25b4b4` | LIVE |
| AIAccountabilityBondsV2 | `0xf92baef9523BC264144F80F9c31D5c5C017c6Da8` | Deployed |
| MissionEnforcement | `0x8568F4020FCD55915dB3695558dD6D2532599e56` | Deployed |
| AntiSurveillance | `0x722E37A7D6f27896C688336AaaFb0dDA80D25E57` | Deployed |
| PrivacyGuarantees | `0xE2f75A4B14ffFc1f9C2b1ca22Fdd6877E5BD5045` | Deployed |
| USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | (canonical Base USDC) |
| ERC8004ValidationRegistry | `0x54e00081978eE2C8d9Ada8e9975B0Bb543D06A55` | Deployed |
| VaultfireERC8004Adapter | `0xef3A944f4d7bb376699C83A29d7Cb42C90D9B6F0` | Deployed |
| FlourishingMetricsOracle | `0x83dd216449B3F0574E39043ECFE275946fa492e9` | Deployed |
| MultisigGovernance | `0x8B8Ba34F8AAB800F0Ba8391fb1388c6EFb911F92` | Deployed |
| VaultfireTeleporterBridge | `0x94F54c849692Cc64C35468D0A87D2Ab9D7Cb6Fb2` | Deployed |
| DilithiumAttestor | `0xBBC0EFdEE23854e7cb7C4c0f56fF7670BB0530A4` | Deployed |
| ProductionBeliefAttestationVerifier | `0xa5CEC47B48999EB398707838E3A18dd20A1ae272` | Deployed |
| BeliefAttestationVerifier | `0xD9bF6D92a1D9ee44a48c38481c046a819CBdf2ba` | Deployed |

**Notes:**
- The USDC address (`0x833589fcd...`) is the canonical USDC address on Base — verified correct.
- Contracts are divided into "LIVE" (actively queried for identity/bonds/VNS data) and "Deployed" (present in the map but queried only for `eth_getCode` presence checks in `fetch_protocol_contracts()`).
- The contract count in `CONTRACTS` dict is 17. Test `test_contract_count` asserts `>= 17`.

---

### 4.3 Function Selectors (ABI)

| Function | Selector | Contract |
|----------|----------|---------|
| `isAgentActive(address)` | `0x554c4f4b` | ERC8004IdentityRegistry |
| `getReputation(address)` | `0x9c89a0e2` | ERC8004ReputationRegistry |
| `resolveAddressToName(address)` | `0x13fee8d3` | VaultfireNameService |
| `getBondsByParticipantCount(address)` | `0x67ff6265` | AIPartnershipBondsV2 |
| `nextBondId()` | `0xee53a423` | AIAccountabilityBondsV2 |
| `totalActiveBondValue()` | `0xe7683e58` | AIAccountabilityBondsV2 |
| `balanceOf(address)` | `0x70a08231` | USDC |

**Important observations:**
- `nextBondId()` and `totalActiveBondValue()` are **global** contract state queries — they return protocol-wide values, not per-address values. This is used in Street Cred scoring but does not reflect the specific address being queried for accountability bonds.
- `getBondsByParticipantCount(address)` is per-address for partnership bonds.
- ABI encoding is done manually using `_encode_address()` (zero-pads to 32 bytes) and `_build_call_data()` (concatenates selector + encoded arg).

---

### 4.4 Feature Implementation Details

#### Trust Verification (`trust <address>`)
Aggregates data from 5 parallel fetches:
- `fetch_identity()` → ERC-8004 active status, VNS name, reputation
- `fetch_bonds()` → partnership bond count, next accountability bond ID, total bond value
- `fetch_protocol_contracts()` → eth_getCode for MissionEnforcement, AntiSurveillance, PrivacyGuarantees
- `fetch_usdc_balance()` → USDC balance on Base
- `fetch_xmtp_status()` → XMTP network reachability

Computes `compute_street_cred()` and displays a formatted trust panel with: Trust Grade (A–F/S), Street Cred (0–95), bond status, identity, VNS name, x402 readiness, XMTP reachability, and protocol commitment flags.

#### Street Cred Scoring (`streetcred <address>`)
```
compute_street_cred(identity_active, bond_count, next_bond_id, reputation):
  + 30  — ERC-8004 identity active
  + 25  — any partnership bond exists (count > 0)
  + 15  — any accountability bond created (next_bond_id > 0)
  +  5  — Bronze tier (reputation >= 1)
  + 10  — Silver tier (reputation >= 2)
  + 15  — Gold tier  (reputation >= 3)
  + 20  — Platinum tier (reputation >= 4)
  +  5  — multiple bonds (count > 1)
  cap at 95
```

Grade thresholds: S (≥85), A (≥75), B (≥60), C (≥45), D (≥30), F (<30)  
Tier thresholds: Platinum (≥80), Gold (≥60), Silver (≥40), Bronze (≥20), None

**Subtlety:** The `reputation` parameter is treated as a raw `uint256` mapped to tier levels (0=None, 1=Bronze, 2=Silver, 3=Gold, 4=Platinum). The tier bonus is exclusive (only the highest matching tier applies), not cumulative. The score cap at 95 is hardcoded — 30+25+15+20+5 = 95 exactly, so the cap is theoretically unreachable in practice but enforced defensively.

#### Identity Check (`identity <address>`)
Three `eth_call`s:
1. `isAgentActive(address)` → bool (ERC8004IdentityRegistry)
2. `resolveAddressToName(address)` → string (VaultfireNameService)
3. `getReputation(address)` → uint256 (ERC8004ReputationRegistry)

#### Bond Status (`bonds <address>`)
Three `eth_call`s:
1. `getBondsByParticipantCount(address)` → uint256 (AIPartnershipBondsV2) — per-address
2. `nextBondId()` → uint256 (AIAccountabilityBondsV2) — **global** (NOT per-address)
3. `totalActiveBondValue()` → uint256 (AIAccountabilityBondsV2) — **global** (NOT per-address)

**Gap:** Bond status for accountability bonds is protocol-wide, not specific to the queried address. The output label "Next Bond ID" represents the next sequential bond ID in the entire contract, not a bond count for the given address. This could mislead users.

#### x402 Payments (`x402 <address>`)
**Actual implementation:** Only checks the USDC (`balanceOf`) on Base for the given address. 

**Gap/Mislabeling:** The command is described as "Trust-gated USDC payment readiness (EIP-712)" but the implementation does **not** perform any EIP-712 signing, trust-gating check, or x402 protocol handshake. It is purely a USDC balance check. The presence of any USDC (>0) is declared "x402 ready". The label "EIP-712" appears in output strings but no EIP-712 logic exists anywhere in the codebase. This is a significant discrepancy between documentation and implementation.

#### XMTP Messaging (`xmtp <address>`)
**Actual implementation:** Sends a generic POST to `https://production.xmtp.network/message/v1/query` with empty `contentTopics`. The `address` parameter is accepted but **never used** in the request. The check only verifies that the XMTP network endpoint returns HTTP 200/206/400 or 422 — i.e., it checks if the XMTP *network* is reachable, not whether the specific address has an XMTP identity.

**Gap:** The function name, documentation, and output claim to check if an "address is reachable on the XMTP network" — but no address-specific lookup is performed. Any address will return "Reachable" as long as the XMTP network is online.

#### Contract Listing (`contracts`)
Returns all 17 entries from the `CONTRACTS` dict with descriptions and BaseScan links. Pure local data — no network call.

#### Hub Stats (`hub`)
HTTP GET to `https://theloopbreaker.com/api/hub/stats`. Returns `agentCount`, `activeBonds`, `ethBonded` from the Vaultfire hub API. Supports both camelCase and snake_case response key formats.

---

### 4.5 RPC & Networking

- **Transport:** Pure `urllib.request` — no `requests`, no `httpx`
- **Fallback logic:** On any `HTTPError`, `URLError`, `TimeoutError`, or `OSError`, the cached RPC is cleared and all fallbacks are tried. If all fail, the original exception is re-raised.
- **Rate limit handling:** HTTP 429 and JSON-RPC error code 429 trigger exponential backoff (1.5s, 3.0s) then retry up to 2 times.
- **Timeout:** 8 seconds per request

---

### 4.6 ABI Decoding

Manually implemented (no `eth_abi`):
- `_decode_bool(hex)` — checks last byte of 32-byte return value
- `_decode_uint256(hex)` — parses 64 hex char value as big-endian int
- `_decode_string(hex)` — ABI-decodes dynamic string: reads offset, length, then UTF-8 bytes
- `_has_code(hex)` — checks if `eth_getCode` result is non-empty (indicates deployed contract)

All decode functions gracefully handle `None` and `"0x"` (empty result) by returning `None` or `False`.

---

## 5. Test Suite Analysis

### Quality: **Excellent**

**Test file:** `tests/test_vaultfire_client.py` (488 lines, 54 tests)  
**All 54 tests pass.** No failures. Run time: 0.06s (all unit/pure tests — no network calls).

### Test Coverage by Class

| Class | Tests | What's Covered |
|-------|-------|----------------|
| `TestValidateAddress` | 6 | valid+prefix, valid no prefix, whitespace, short, invalid hex, empty |
| `TestEncodeAddress` | 3 | 64 char output, 0x stripped, lowercase |
| `TestBuildCallData` | 2 | selector only, selector + address (74 chars) |
| `TestDecodeBool` | 4 | true, false, None/empty, non-zero |
| `TestDecodeUint256` | 4 | zero, one, 1 ETH in wei, None/empty |
| `TestDecodeString` | 4 | None/empty, short data, empty string, "hello" |
| `TestHasCode` | 3 | no code (None/0x/0x0), has code, empty string |
| `TestShortAddress` | 2 | with/without 0x prefix → "0x8335...2913" format |
| `TestStreetCred` | 9 | zero score, identity only (+30), bond exists (+25), bond active (+15), multiple bonds (+5), Platinum (+20), Gold (+15), max cap at 95, None inputs |
| `TestContractMap` | 5 | all valid hex, no duplicates, required names present, USDC canonical address, count >= 17 |
| `TestSelectors` | 2 | 7 known selector values, all 4-byte format |
| `TestConfig` | 3 | chain ID = 8453, fallbacks non-empty, all HTTPS |
| `TestCLIParser` | 5 | trust cmd, hub cmd, contracts cmd, --json flag, all 8 commands |

### What Tests Do NOT Cover
- Integration/live tests against the Base RPC
- `fetch_identity()`, `fetch_bonds()`, `fetch_usdc_balance()`, `fetch_xmtp_status()`, `fetch_hub_stats()` — no network mocking
- `cmd_trust()`, `cmd_streetcred()`, `cmd_identity()`, `cmd_bonds()`, `cmd_x402()`, `cmd_xmtp()`, `cmd_contracts()`, `cmd_hub()` — no output format testing
- `_rpc_request()`, `_rpc_call()`, `eth_call()`, `eth_get_code()` — no mock HTTP testing
- `_decode_string()` multi-byte UTF-8 / multi-slot string decoding edge cases
- Error propagation in fetch functions
- `main()` end-to-end CLI

---

## 6. Integration Approach: How It Hooks Into Hermes

The integration uses the **Hermes skill architecture** where:

1. **SKILL.md** acts as the skill manifest — it contains YAML frontmatter with metadata (`name`, `description`, `version`, `tags`, `related_skills`) and a natural-language procedural guide for the Hermes LLM to follow.

2. **Installation** copies the repo to `~/.hermes/skills/vaultfire/`. The Hermes agent skill loader reads `SKILL.md` from this path.

3. **Invocation** happens when the LLM determines the skill is relevant (based on the "When to Use" triggers in SKILL.md) and executes `vaultfire_client.py` as a subprocess with the appropriate command and address argument.

4. **Output formats:** `--json` flag enables machine-readable JSON for programmatic consumption; default is formatted human-readable output with Unicode decorations.

The integration approach is **subprocess-based** — the Hermes agent calls Python as an external process rather than importing the module. This is why `main()` has `if __name__ == "__main__": sys.exit(main())` and all commands return integer exit codes.

**No direct Hermes SDK imports** exist in the codebase. The skill does not use any `hermes.*` namespace or call any Hermes APIs. It is a standalone CLI tool that Hermes wraps via its skill dispatcher.

---

## 7. Supported Chains

**Single chain only:** Base Mainnet (`CHAIN_ID = 8453`).

No multi-chain support. The `VaultfireTeleporterBridge` contract is listed in the contract map (with description "Teleporter cross-chain bridge") but is never queried. No cross-chain functionality is implemented.

---

## 8. Environment Variables

| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `VAULTFIRE_RPC_URL` | No | `""` (uses `_RPC_FALLBACKS`) | Custom Base RPC endpoint |
| `VAULTFIRE_AGENT_KEY` | Mentioned in docs | Not implemented | Agent private key for write ops |
| `VAULTFIRE_AGENT_ADDRESS` | Mentioned in docs | Not implemented | Agent address for read-only bond checks |

**Gap:** `VAULTFIRE_AGENT_KEY` and `VAULTFIRE_AGENT_ADDRESS` are documented in README but **never referenced in `vaultfire_client.py`**. No `os.environ.get("VAULTFIRE_AGENT_KEY")` call exists. Write operations (bond creation, x402 signing) are documented as future features requiring these variables, but no stub or placeholder exists in code.

---

## 9. Gaps, TODOs, and Incomplete Features

### Critical Gaps

1. **XMTP check is not address-specific.** `fetch_xmtp_status(address)` ignores the `address` argument entirely. It only verifies the XMTP network is online. Every address returns "Reachable" when the XMTP service is up.

2. **x402 is not implemented.** The `x402` command only checks USDC balance. No EIP-712 signing, no x402 protocol handshake, no trust-gating logic. The description "trust-gated USDC payment readiness (EIP-712)" is misleading — it should be "USDC balance check."

3. **Accountability bond query is global, not per-address.** `nextBondId()` and `totalActiveBondValue()` are state variables on the AIAccountabilityBondsV2 contract, not per-address lookups. The current implementation cannot tell whether a specific address holds an accountability bond.

4. **Write operations are entirely absent.** `VAULTFIRE_AGENT_KEY` is mentioned in README and SKILL.md pitfalls ("write operations require VAULTFIRE_AGENT_KEY") but there is zero write-operation code. No bond creation, no x402 payment initiation, no VNS name registration.

### Minor Gaps

5. **`related_skills: [base]`** — references a Hermes `base` skill not shipped with this repo and not publicly documented.

6. **`hermes skills install vaultfire`** — marked as future ("when published to Skills Hub"). No Skills Hub URL or ETA provided.

7. **No Python version constraint documented** — code uses `str | None` union syntax (Python 3.10+), `dict | None` (3.10+). README and SKILL.md do not state the minimum Python version.

8. **No `requirements.txt` or dependency declaration** — intentional given stdlib-only design, but a `pyproject.toml` with Python version constraint would be standard practice.

9. **`DilithiumAttestor` contract** — described as "Post-quantum attestor (Dilithium)" but never queried. Listed only in the contracts map.

10. **`FlourishingMetricsOracle`** — listed but never queried. Its purpose (beyond the name) is undocumented.

11. **`fetch_protocol_contracts()` checks only 3 of 9 "extra" contracts** via `eth_getCode`. The other contracts (ERC8004ValidationRegistry, VaultfireERC8004Adapter, FlourishingMetricsOracle, MultisigGovernance, VaultfireTeleporterBridge, DilithiumAttestor, ProductionBeliefAttestationVerifier, BeliefAttestationVerifier) are listed but otherwise unused.

12. **No TODOs or FIXMEs in source code** — the code contains no explicit `TODO`/`FIXME`/`HACK` comments. Missing features are only implied by the README documentation vs. implementation gap.

13. **Hub API dependency** — `fetch_hub_stats()` calls `https://theloopbreaker.com/api/hub/stats`. This is an external centralized API that could go offline. There is no fallback or cached/mock data if the hub is unavailable.

---

## 10. SDK Reference

The skill does **not** use the Vaultfire SDK. All Vaultfire contract interaction is done via raw `eth_call` JSON-RPC with manually computed ABI selectors and hand-rolled ABI decoding. This is a deliberate design choice stated in the README: "No API keys. No external dependencies. Just Python standard library and live blockchain data."

The README links to:
- `github.com/Ghostkey316/ghostkey-316-vaultfire-init` (Vaultfire Protocol)
- `github.com/Ghostkey316/vaultfire-base` (Vaultfire on Base)

But neither is imported or required. The contract addresses are hardcoded directly. This makes the skill self-contained but means:
- ABI changes in the contracts would require manually updating selectors in `SELECTORS` dict
- No type safety from an SDK's typed contract interfaces
- Decoding complex return types (structs, tuples) would require significant manual work

---

## 11. Documentation Quality Summary

| Document | Quality | Notes |
|----------|---------|-------|
| README.md | Good | Clear, well-structured, complete feature table. Missing: Python version, test instructions, write-op status |
| SKILL.md | Excellent | Comprehensive procedural guide for LLM skill invocation; covers prerequisites, pitfalls, all commands |
| Inline code docs | Good | All public functions have docstrings. Constants are commented. Section headers are clear |
| Test docstrings | Good | Each test class and test method has a descriptive docstring |

---

## 12. Overall Assessment

### Strengths
- **Zero-dependency design** — stdlib-only makes it extremely portable and easy to audit
- **Robust RPC fallback chain** — 4 public endpoints, automatic failover, exponential backoff on 429
- **Strong test coverage** for pure logic** — 54 passing unit tests covering all helper functions and scoring logic
- **Well-structured output** — both human-readable (formatted with Unicode) and machine-readable (`--json`) modes
- **Thoughtful SKILL.md** — the "When to Use" triggers and "Pitfalls" sections are production-quality Hermes skill documentation
- **Clean Python** — consistent style, type annotations throughout, proper error handling with graceful None propagation
- **No hardcoded secrets** — all sensitive config via environment variables

### Weaknesses
- **XMTP check is effectively a network ping**, not an address-specific lookup — a fundamental correctness issue
- **x402 is a USDC balance check**, not an EIP-712/x402 protocol implementation — significant gap between docs and code
- **Accountability bond check is global**, not per-address — misleads users about individual bond status
- **Write operations are entirely absent** despite being documented as supported with env vars
- **No CI/CD** — tests run manually; no automation pipeline
- **No integration tests** — `fetch_*` functions and full command flows are untested end-to-end
- **Single chain** — Base mainnet only, despite a `VaultfireTeleporterBridge` contract in the map

### Maturity Rating: **Beta / Pre-release (0.1.0)**
The core read-only trust verification pipeline (identity + reputation + partnership bonds + Street Cred scoring) is solid and well-tested. The XMTP and x402 features are incomplete stubs. Write operations (bond creation, x402 payments) are not implemented. The skill is suitable for read-only KYA lookups in a Hermes agent context.
