---
name: trust-domain-discovery
title: Trust Domain Discovery
description: Observe the decision log, cluster unmapped contract actions, propose new trust domains for user approval.
category: _meta
status: active
priority: 6
author: agent
---

## Purpose

AgntSpace trust is per-domain. When a new contract action is added (a new tool, a new integration, a new plugin), it falls into the `general` domain until a human remaps it in `trust-evolution/config/domains.yaml`. That's a friction point: users rarely know they need to do this until behavior feels off ("why is the agent asking for confirmation on `github_comment`? It should be in the `github` domain with my other github actions"). This skill is the agent's way of noticing the friction and proposing fixes before the user has to.

## How It Works

The discovery engine walks the decision log and looks for contract actions whose `trust_domain` is `general` — the catch-all bucket. It then asks two questions about each pair of undomained actions:

1. **Do they co-occur in the same correlation chain?** If the user clicks a button that triggers `github_list_prs → github_get_pr → github_comment`, all three share one correlation_id. That's evidence they belong together.
2. **Do they share a lexical prefix or suffix?** `github_*`, `jira_*`, `notion_*` — a shared stem is a strong cluster signal that complements co-occurrence.

Clusters that pass both the minimum-size and minimum-evidence thresholds become **proposals**. A proposal is NEVER applied automatically — it shows up in `GET /api/trust/domain-proposals`, and the user either approves (YAML gets updated) or dismisses (proposal goes into a cooldown so the same cluster doesn't re-propose until new evidence arrives).

## Rules

1. Discovery is **read-only by default**. The engine never writes to `domains.yaml` without user approval.
2. **Cooldown applies to dismissed proposals** — a rejected cluster waits the full `proposal_cooldown_days` before being re-proposed, so users can't be nagged about the same shape repeatedly.
3. **Minimum evidence is a hard floor**. Five co-occurrences across three distinct correlation chains is the smallest signal we'll propose on — below that, the cluster is noise.
4. Proposals carry their **evidence count** and **justification** so the user can verify the suggestion rather than trust it blindly. The skill is a proposer, not an arbiter.
5. **Never propose renaming existing domains.** Discovery only creates; it never restructures what the user has already approved. If reorganization is needed, that's a skill-school "suggest_contract_change" proposal, not a discovery proposal.

## What a proposal looks like

```json
{
  "suggested_name": "github (auto-discovered)",
  "contract_actions": ["github_list_prs", "github_get_pr", "github_comment"],
  "evidence": {
    "total_occurrences": 23,
    "distinct_correlation_chains": 8,
    "days_of_evidence": 12,
    "shared_prefix": "github_",
    "co_occurrence_matrix": {"github_list_prs↔github_get_pr": 6, ...}
  },
  "justification": "These 3 actions co-occur in 6 correlation chains and share the 'github_' prefix. Proposing 'github' as a new trust domain."
}
```

## Why this belongs as a skill, not a CLI one-shot

The thresholds, the clustering heuristics, the minimum-cluster-size, and the cooldown are all load-bearing tunings that a user may reasonably want to adjust without a code change. They live in `config/discovery.yaml`. The Python engine is a pure executor of that config. Rule 12.
