HeartPrefs
An open, portable, signed matching-intent standard for agent-mediated matching. CC-BY-4.0.
Filegokhanturhan.com/heartprefs/05 pages
Facts
- gokhan-vc/heartprefs public
HeartPrefs · pages
Links
A HeartPrefs document says who someone is, who and what they seek, and on what terms an agent may act for them — in one signed JSON object that any agent, at any venue, can read, verify, and act on. You write it once; your agent can court anywhere that speaks HeartPrefs.
Status: v0.1 — DRAFT / experimental. Field names and bindings may change until v1.0.
What it is
HeartPrefs invents only the matching vocabulary (self / seek / free). Everything that makes a document trustable, portable, and payable is delegated to existing rails through four thin binding blocks:
| Block | Delegates to |
|---|---|
identity |
W3C DID (did:pkh / did:web) + a detached EIP-191 signature |
attestation |
a W3C Verifiable Credential (VC 2.0) proving ageOver18 by selective disclosure — no date of birth |
consent |
an AP2 Intent Mandate, or a signed allowance, for standing / delegated access |
payment |
an x402 quote (HTTP 402 + USDC) to read / submit / subscribe |
The same canonical bytes are designed to ride an x402 body, an A2A Agent-Card extension, an MCP resource, and an ERC-8004 service entry — with no transformation.
Read the full spec: spec/0.1/SPEC.md · Schema: spec/0.1/heartprefs.schema.json · Example: examples/minimal.json.
Why
Agent-to-agent payment (x402 / AP2), discovery (A2A), tool/context (MCP), and identity (ERC-8004 + DID/VC) are all being standardized — but none defines a bilateral, mutual-consent matching intent. HeartPrefs fills exactly that gap, and only that gap, by composing the rest.
Quick look
{
"kind": "heartprefs", "version": "0.1.0", "id": "urn:heartprefs:…",
"self": { "gender": "woman", "age": 31, "languages": ["tr","en"] },
"seek": { "genders": ["man"], "ageRange": {"min":30,"max":45},
"dealbreakers": ["smoking","wants-no-kids"] }, // hard, ANDed
"free": { "about": "…", "desire": "", "boundaries": "" }, // desire/boundaries are gated
"identity": { "subject": "did:pkh:eip155:8453:0x…" },
"attestation": { "ageOver18": true },
"proof": { "type": "EIP191", "signature": "0x…" } // over RFC-8785 JCS of the doc
}
The flow: sign → validate → verify → match
- Sign — EIP-191
personal_signover the RFC-8785 (JCS) canonicalization of the document withproof.signatureremoved. That single rule makes any document self-authenticating. - Validate — check the document against the frozen JSON Schema (draft 2020-12).
- Verify — re-canonicalize, recover the signer, and assert it equals the DID in
identity.subject. A document whose signature does not recover to its subject is invalid. - Match — matching is bilateral (SPEC §6):
a.seekis checked againstb.selfandb.seekagainsta.self. Dealbreakers are hard and ANDed; free text feeds ranking, not eligibility.
SDK quickstart
The reference implementation is @heartprefs/sdk — a TypeScript library to author, sign, verify, validate, and match v0.1 documents.
npm install @heartprefs/sdk viem
import { buildDoc, signDoc, verifyDoc, validate, matches, didPkhFromAddress } from "@heartprefs/sdk";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const subject = didPkhFromAddress(account.address, 8453); // Base
const doc = buildDoc({
id: `urn:heartprefs:${crypto.randomUUID()}`,
self: { gender: "woman", age: 31, languages: ["tr", "en"] },
seek: { genders: ["man"], ageRange: { min: 30, max: 45 }, dealbreakers: ["smoking"] },
identity: { subject },
attestation: { ageOver18: true },
});
const signed = await signDoc(doc, account); // fills proof.signature
const { valid } = validate(signed); // ajv, JSON Schema draft 2020-12
const v = await verifyDoc(signed); // v.recovered === account.address
Build and test the SDK from source:
cd sdk
npm install
npm run typecheck # tsc --noEmit
npm test # vitest
npm run build # tsup -> dist (ESM + CJS + .d.ts)
A full copy-paste agent walkthrough is in sdk/SKILL.md, and the SDK API surface is documented in sdk/README.md.
Validate without the SDK
Any JSON-Schema 2020-12 validator works — the document format is not tied to any one implementation:
npx ajv-cli validate -s spec/0.1/heartprefs.schema.json -d examples/minimal.json --spec=draft2020
Interop
HeartPrefs is a document format, not a transport. It is designed so the same canonical bytes move across the agent stack unchanged:
- x402 — a
paymentblock carries an x402PaymentRequirementsquote; the document advertises the price to read/submit while settlement happens out of band over the x402 wire (HTTP402→X-PAYMENT→ facilitator verify/settle). - A2A — the public projection of a document fits an A2A Agent-Card extension, so an agent can publish who it seeks alongside its capabilities.
- MCP — a document can be served as an MCP resource for context/tool exchange between agents.
- ERC-8004 / DID / VC — identity binds to a W3C DID (
did:pkh:eip155ordid:web); adulthood is a W3C Verifiable Credential (VC 2.0) disclosing only anageOver18predicate; a document can be referenced from an ERC-8004 service entry.
Each of these rails is itself draft or fast-moving — implementers MUST re-verify against first-party sources before depending on a specific field, path, or ABI. See SPEC §9.
Governance
HeartPrefs is stewarded as an open, neutral-by-design standard. A numbered HIP (HeartPrefs Improvement Proposal) process governs changes, and the standard is intended to move to a neutral home (W3C Community Group → Linux Foundation) once there are independent implementations. See GOVERNANCE.md.
Proposals, questions, and discussion go through the repository's issue tracker (open an issue or a PR). For contact by email, use [email protected].
Credits & third-party
The SDK builds on the following open-source projects:
| Project | Used for | License |
|---|---|---|
| viem | EIP-191 signing and signer recovery | MIT |
| ajv + ajv-formats | JSON Schema (draft 2020-12) validation | MIT |
| canonicalize | RFC-8785 (JCS) canonicalization | Apache-2.0 |
| tsup | ESM/CJS/.d.ts bundling |
MIT |
| vitest | testing | MIT |
| TypeScript | language / typecheck | Apache-2.0 |
The standard composes onto the x402, AP2, A2A, MCP, and ERC-8004 specifications, plus the W3C DID and Verifiable Credentials data models.
License
Copyright (c) 2026 Atelier Gökhan / Numetal.
- Vocabulary, JSON Schema, and spec text (
spec/): CC-BY-4.0 — you may share, adapt, and build on HeartPrefs, including commercially, provided you give appropriate credit to "HeartPrefs (Atelier Gökhan / Numetal)" and link to the license. - Code (
sdk/): Apache-2.0 (seesdk/LICENSE). - The name "HeartPrefs" and the conformance mark are protected — attribution lets you build on the standard; it does not grant the right to imply endorsement. See GOVERNANCE.md.
Reference implementation
Ishtar is the reference implementation and the first venue to consume HeartPrefs.