> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bensevern.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ER agent

> GoldenMatch as an autonomous entity resolution agent: A2A protocol, 47 skills, confidence-gated review queue, and Python API.

GoldenMatch exposes itself as an autonomous entity resolution agent that other AI systems can discover and invoke.

An agent says "deduplicate this data" and GoldenMatch handles strategy selection, config generation, pipeline execution, and result explanation -- all without human configuration.

<Tip>
  Just want to use from Claude Desktop? See the [MCP Server](/docs/goldenmatch/mcp) page instead -- it's simpler for human-in-the-loop workflows.
</Tip>

## What is A2A?

**A2A (Agent-to-Agent)** is an open protocol for AI systems to discover and invoke each other. Think of it as DNS + HTTP for AI agents:

1. An agent discovers GoldenMatch at `/.well-known/agent.json` (like a business card)
2. The agent card lists **skills** (capabilities) with input/output schemas
3. The calling agent sends a task, GoldenMatch processes it, returns structured results

A2A is supported by LangChain, CrewAI, AutoGen, and other agent frameworks. Use A2A when you're building **agent-to-agent workflows** where no human is in the loop.

## Two Protocols

| Protocol                         | Port  | Best For                                         | When to Use                                     |
| -------------------------------- | ----- | ------------------------------------------------ | ----------------------------------------------- |
| **A2A** (Agent-to-Agent)         | 8200  | AI agent frameworks (LangChain, CrewAI, AutoGen) | Agent-to-agent automation, no human in the loop |
| **MCP** (Model Context Protocol) | stdio | Claude Desktop, Cursor, Windsurf                 | Human-in-the-loop, interactive AI assistants    |

## Quick Start

### A2A Server

```bash theme={null}
pip install goldenmatch[agent]
goldenmatch agent-serve --port 8200
```

Other agents discover GoldenMatch at:

```text theme={null}
GET http://localhost:8200/.well-known/agent.json
```

### MCP (Claude Desktop)

Add to `claude_desktop_config.json`:

```json theme={null}
{
  "mcpServers": {
    "goldenmatch": {
      "command": "goldenmatch",
      "args": ["mcp-serve", "--file", "customers.csv"]
    }
  }
}
```

## Agent Capabilities (40 Skills)

<Note>
  **Cross-language skill ids.** The TypeScript and Python A2A servers share
  canonical skill ids for the core operations (`deduplicate`, `match`, `explain`,
  `evaluate`, `analyze_data`, the `identity_*` set, ...), and every skill on both
  cards is A2A-spec-shaped (`id` + a human-readable `name`). For back-compat the
  TypeScript server also dispatches the legacy ids `dedupe` and `explain_pair`. The
  two catalogs otherwise differ by design -- each server exposes skills the other
  does not -- so A2A is documented for parity, not CI-gated (MCP tools + CLI are).
</Note>

### Core & pipeline

| Skill                  | What It Does                                                                                                                                                                            |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `analyze_data`         | Profile columns, detect domain, recommend matching strategy                                                                                                                             |
| `configure`            | Generate optimal YAML config from data analysis (legacy heuristic path)                                                                                                                 |
| `autoconfig`           | **v1.7-v1.12**: run AutoConfigController; return committed config + telemetry (stop\_reason, decisions, NE / Path Y)                                                                    |
| `controller_telemetry` | **v1.7-v1.12**: surface controller telemetry from the most recent call (stateless A2A dispatch → returns inline note pointing callers at `autoconfig` / `deduplicate` inline telemetry) |
| `deduplicate`          | Full pipeline with confidence-gated output, reasoning, and **telemetry** (v1.7+)                                                                                                        |
| `match`                | Cross-source matching with intelligent strategy selection and **telemetry** (v1.7+)                                                                                                     |
| `explain`              | Natural language explanation for any pair or cluster                                                                                                                                    |
| `review`               | Present borderline matches for approval                                                                                                                                                 |
| `compare_strategies`   | Run multiple approaches, report metrics                                                                                                                                                 |
| `pprl`                 | Privacy-preserving mode for sensitive data                                                                                                                                              |
| `quality`              | Scan and fix data quality issues (encoding, Unicode, format violations) using GoldenCheck                                                                                               |
| `transform`            | Normalize data formats (phone E.164, dates ISO, categorical spelling) using GoldenFlow                                                                                                  |

### Analysis & operations

| Skill              | What It Does                                                                                        |
| ------------------ | --------------------------------------------------------------------------------------------------- |
| `evaluate`         | Score accuracy (precision/recall/F1) against a ground-truth pair CSV                                |
| `analyze_blocking` | Rank blocking-key candidates: block counts, max block size, candidate-pair totals, estimated recall |
| `compare_clusters` | Compare two ER outcomes (CCMS / Talburt-Wang Index)                                                 |
| `schema_match`     | Auto-map columns between two files with different schemas                                           |
| `sensitivity`      | Sweep config parameters and report clustering stability at each value                               |
| `incremental`      | Match a batch of new records against an existing base dataset                                       |
| `list_runs`        | List previous runs from the run log (for rollback)                                                  |
| `rollback`         | Undo a previous run by deleting its outputs (destructive)                                           |
| `review_config`    | Run the config-suggestion (healer) loop and return advisory suggestions                             |
| `retrieve_similar` | Retrieve records similar to a query value on a given column                                         |

### Identity Graph (v2.0)

| Skill                       | What It Does                                           |
| --------------------------- | ------------------------------------------------------ |
| `identity_resolve`          | Resolve a record\_id to its durable identity           |
| `identity_show`             | Full detail of one identity by entity\_id              |
| `identity_list`             | List identities, optionally filtered by dataset/status |
| `identity_history`          | Temporal event log for an identity                     |
| `identity_conflicts`        | Evidence edges marked `conflicts_with`                 |
| `identity_merge`            | Manually merge two identities                          |
| `identity_split`            | Split records off an identity into a new one           |
| `identity_claim`            | Claim/assign a record to a specific durable identity   |
| `identity_resolve_conflict` | Resolve a flagged `conflicts_with` edge                |
| `identity_audit`            | Audit-log entries for identity mutations               |
| `identity_audit_seal`       | Seal the audit log (tamper-evident checkpoint)         |
| `identity_audit_verify`     | Verify the audit log seal chain                        |

### Learning Memory

| Skill              | What It Does                                                       |
| ------------------ | ------------------------------------------------------------------ |
| `add_correction`   | File a pair- or field-level correction (source=`agent`, trust 0.5) |
| `list_corrections` | Page through stored corrections, filtered by dataset               |
| `learn_thresholds` | Run the MemoryLearner; return per-matchkey threshold adjustments   |
| `memory_stats`     | Correction counts, last-learned timestamps, current adjustments    |

## How It Works

When an agent calls `deduplicate`, GoldenMatch:

1. **Profiles** the data (column types, cardinality, null rates)
2. **Detects** the domain (healthcare, financial, retail, people, etc.)
3. **Selects** the best strategy:
   * Strong ID fields (email, SSN) -> exact matching
   * Fuzzy-matchable fields (name, address) -> fuzzy matching
   * Sensitive fields detected -> recommends PPRL
   * Large datasets (>500K) -> recommends Ray backend
4. **Generates** a config (matchkeys, blocking, scoring)
5. **Runs** the pipeline with confidence gating
6. **Returns** results + reasoning

### Reasoning Output

Every response includes the agent's reasoning:

```json theme={null}
{
  "results": {
    "clusters": 42,
    "match_rate": "8.4%"
  },
  "reasoning": {
    "domain_detected": "people",
    "strategy_chosen": "exact_then_fuzzy",
    "why": "Email has 92% uniqueness -- strong exact key. Name has spelling variation -- jaro_winkler at 0.85.",
    "alternatives_considered": [
      {"strategy": "pprl", "why_not": "No sensitive fields detected."},
      {"strategy": "fellegi_sunter", "why_not": "Fuzzy gives better recall for this data."}
    ],
    "confidence_distribution": {
      "auto_merged": 38,
      "review_queue": 4,
      "auto_rejected": 0
    }
  },
  "storage": "memory"
}
```

## Confidence-Gated Review Queue

Not all matches are equal. The agent splits results by confidence:

| Confidence  | Action                            | Count                 |
| ----------- | --------------------------------- | --------------------- |
| > 0.95      | Auto-merged into golden records   | High-confidence pairs |
| 0.75 - 0.95 | Held in review queue for approval | Borderline pairs      |
| \< 0.75     | Auto-rejected                     | Low-confidence pairs  |

### Storage Tiers

| Tier         | Config                             | Persists?        |
| ------------ | ---------------------------------- | ---------------- |
| **Memory**   | Default (nothing to configure)     | No               |
| **SQLite**   | Create a `.goldenmatch/` directory | Yes (local file) |
| **Postgres** | Set `DATABASE_URL` env var         | Yes (shared DB)  |

The agent auto-detects which tier is available and reports it in every response.

### Review Queue API

```python theme={null}
from goldenmatch import AgentSession

session = AgentSession()
result = session.deduplicate("customers.csv")

# Check what needs review
pending = session.review_queue.list_pending("customers")
for item in pending:
    print(f"Pair ({item.id_a}, {item.id_b}): score={item.score}")
    print(f"  Explanation: {item.explanation}")

# Approve or reject
session.review_queue.approve("customers", 0, 1, decided_by="human")
session.review_queue.reject("customers", 2, 3, decided_by="human", reason="Different entities")

# Stats
print(session.review_queue.stats("customers"))
# {"pending": 2, "approved": 1, "rejected": 1}
```

## Python API

```python theme={null}
from goldenmatch import AgentSession

session = AgentSession()

# Analyze data and get strategy recommendation
analysis = session.analyze("customers.csv")
print(analysis["strategy"])  # "exact_then_fuzzy"
print(analysis["why"])

# Deduplicate with full reasoning
result = session.deduplicate("customers.csv")
print(result["results"]["clusters"])
print(result["reasoning"]["why"])

# Compare strategies
comparison = session.compare_strategies("customers.csv")
for strategy, metrics in comparison.items():
    print(f"{strategy}: {metrics['clusters']} clusters, {metrics['match_rate']:.1%} match rate")

# Match two sources
matches = session.match_sources("new_customers.csv", "master.csv")

# v1.7-v1.12: explicit AutoConfigController invocation
autoconf = session.autoconfigure("customers.csv")
print(autoconf["telemetry"]["stop_reason"])     # e.g. "green"
print(autoconf["telemetry"]["health"])          # e.g. "green"
for decision in autoconf["telemetry"]["decisions"]:
    print(f"iter {decision['iteration']}: {decision['rule_name']}")

# Telemetry is also cached on `deduplicate` / `match_sources` calls
session.deduplicate("customers.csv")
print(session.last_telemetry)                    # same shape as autoconfigure's telemetry
```

## MCP Tools (18 Agent-Level)

| Tool                       | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| `analyze_data`             | Profile data, detect domain, recommend strategy                                    |
| `auto_configure`           | Generate optimal config                                                            |
| `controller_telemetry`     | Surface AutoConfigController telemetry (per-session note under stateless dispatch) |
| `agent_deduplicate`        | Full pipeline with reasoning                                                       |
| `agent_match_sources`      | Cross-source matching                                                              |
| `agent_explain_pair`       | Explain a pair match                                                               |
| `agent_explain_cluster`    | Explain a cluster                                                                  |
| `agent_review_queue`       | Get pending reviews                                                                |
| `agent_approve_reject`     | Process review decisions                                                           |
| `agent_compare_strategies` | Compare ER approaches                                                              |
| `suggest_pprl`             | Check if PPRL is needed                                                            |
| `scan_quality`             | Run GoldenCheck data quality scan, return issues without fixing                    |
| `fix_quality`              | Run GoldenCheck scan and apply fixes (safe or moderate mode)                       |
| `run_transforms`           | Run GoldenFlow transforms (phone E.164, dates ISO, Unicode)                        |
| `sensitivity`              | Parameter-sweep stability analysis                                                 |
| `incremental`              | Match new records against an existing base dataset                                 |
| `certify_recall`           | Certify recall on the loaded dataset                                               |
| `retrieve_similar`         | Retrieve records similar to a query value on a column                              |

These are additive -- existing MCP tools (`suggest_config`, `list_domains`, etc.) continue to work. The full MCP surface is **69 tools** spanning agent-level ER, data inspection, config suggestions, PPRL, Learning Memory, and Identity Graph -- see [MCP Server](/docs/goldenmatch/mcp).

## A2A Agent Card

```json theme={null}
{
  "name": "GoldenMatch ER Agent",
  "description": "Autonomous entity resolution agent for deduplication, matching, and data quality.",
  "url": "http://localhost:8200",
  "version": "2.8.0",
  "provider": {
    "organization": "GoldenMatch",
    "url": "https://github.com/benseverndev-oss/goldenmatch"
  },
  "capabilities": {
    "streaming": false,
    "pushNotifications": false
  },
  "skills": [
    {
      "id": "deduplicate",
      "name": "Deduplicate",
      "description": "Run deduplication pipeline on a single file.",
      "inputModes": ["application/json"],
      "outputModes": ["application/json"]
    }
  ],
  "authentication": {
    "schemes": ["bearer"]
  }
}
```

Full card at: `http://localhost:8200/.well-known/agent.json`

## Authentication

The server is fail-closed: binding to a non-loopback host (the default is
`0.0.0.0`) refuses to start unless `GOLDENMATCH_AGENT_TOKEN` is set. When the
token is set, all task endpoints require it as a bearer token; `GET /health`
and the agent card at `/.well-known/agent.json` stay public for healthchecks
and discovery.

```bash theme={null}
export GOLDENMATCH_AGENT_TOKEN="your-secret-token"
goldenmatch agent-serve --port 8200
```

Binding to `127.0.0.1` runs token-free for local use.

<Note>
  The agent card advertises `"streaming": false` — task dispatch is synchronous.
  Poll `GET /tasks/{task_id}` for long-running skills.
</Note>

## See also

| Topic                         | Link                                        |
| ----------------------------- | ------------------------------------------- |
| MCP Server (Claude Desktop)   | [MCP Server](/docs/goldenmatch/mcp)              |
| Quick start with Python/CLI   | [Quick Start](/docs/goldenmatch/quickstart)      |
| Full Python API (194 exports) | [Python API](/docs/goldenmatch/python-api)       |
| Configuration reference       | [Configuration](/docs/goldenmatch/configuration) |
