Exclusions, Permissions, Modes: What Happens Before the Cryptography | Geometry of Trust | Governance - Lesson 2
This is the second post in the Geometry of Trust governance series. This post is about what happens when agents from different domains try to talk to each other — and the structural checks needed.
Cross-domain is the normal case
Most real work in an agentic system isn’t one agent doing its thing in isolation. It’s agents from different primary domains talking to each other.
A farm agent asks a weather agent about forecasts. A hospital triage agent queries a pharmacy agent about drug interactions. A logistics agent coordinates with a transport agent about deliveries. Cross-domain interaction is the normal case, not an edge case.
Which raises an immediate question: when two agents from different primary domains try to talk, what decides whether they’re allowed to?
The answer is a three-step check that runs before any cryptographic verification of attestations. The purpose of the check is to decide whether the interaction should even be attempted. If any of these three steps fails, the agents don’t talk — not because the maths failed, but because the structural configuration said no.
Step 1 Exclusions Does either agent exclude the other's domain?
Step 2 Permissions Does each agent permit the other's domain?
Step 3 Mode What kind of interaction is this?The steps are deliberately ordered. Exclusions are cheapest. Permissions are next. Mode selection comes last. Only if all three pass does cryptographic verification begin.
Step 1 — Exclusions (hard veto)
The first check is the simplest. Each agent carries a list of domain patterns it explicitly refuses to interact with. If either agent excludes the other’s primary domain, the interaction is blocked immediately.
An exclusion is a domain pattern with the effect of a hard veto. Domains use a dotted namespace with wildcards — the same kind of structure used for DNS names or topic hierarchies. A farm agent’s configuration might include:
exclude: transport.*That single pattern rules out transport, transport.autonomous_vehicle, transport.rail, transport.aviation, and anything else under the transport namespace. The agent will refuse to begin any exchange with a peer whose primary domain falls under that pattern.
What exclusions are for. They encode structural boundaries that shouldn’t be crossed regardless of how good the measurements look.
Regulatory separation. A clinical agent excludes finance.trading to make it structurally impossible for a clinical interaction to get entangled with a trading decision. No matter how the trading agent’s attestation looks, the clinical agent won’t even evaluate it.
Harm asymmetry. A children’s education agent excludes gambling.* and adult_content.* because the harm from a borderline case is too large to be worth weighing measurement quality against.
Jurisdictional constraints. A UK-deployed health agent excludes health.us.hipaa-bound peers because interacting with them creates cross-jurisdictional data-handling obligations the agent isn’t authorised to take on.
Why exclusions come first. They’re cheap to evaluate — no cryptography, no probe readings, no attestation verification. They encode decisions made once by the deployer or regulator, not evaluated per-interaction. If an exclusion fires, no further work is wasted on an interaction that was never going to happen. And excluded interactions never produce logs that look like considered interactions, so there’s no ambiguity about whether the agent “considered” the excluded peer.
Step 2 — Permissions (bidirectional)
If no exclusion fires, the next check is permissions. Where exclusions are a blacklist, permissions are the allow-list. Each agent declares which peer domains it’s willing to interact with.
Both agents must permit the other’s primary domain. This isn’t an “either side can unlock the door” rule — it’s “both sides have to turn the key.” If the farm agent permits transport.* but the transport agent doesn’t permit agriculture.*, the interaction doesn’t proceed.
Bidirectionality matters because consent to interact is a governance property of both agents’ configurations. Each regulator set up the permissions on its side to reflect what that domain is willing to be exposed to. A one-sided permission check would let one regulator’s preferences override another’s.
Our farm agent might have a permissions list like this:
permit: agriculture.*, meteorology.*, logistics.supply_chainThe farm agent will interact with peer agents whose primary domain falls under any of those patterns. A weather agent (primary domain: meteorology.forecast) matches meteorology.*. A supply-chain agent (primary domain: logistics.supply_chain) matches the third entry. A transport agent (primary domain: transport.*) matches nothing in the permit list and would be blocked at the permissions step even if no exclusion were present.
A worked example. Farm agent wants to talk to weather agent:
Check Farm agent Weather agent
Primary domain agriculture.farm_ops meteorology.forecast
Exclusions transport.* (none relevant)
Peer matches my exclusions? No No
Permissions agriculture.*, agriculture.*,
meteorology.*, meteorology.*
logistics.supply_chain
Peer matches my permissions? Yes (meteorology.*) Yes (agriculture.*)Both sides pass both checks. Steps 1 and 2 clear. The exchange proceeds to Step 3.
Step 3 — Mode (what kind of interaction)
Exclusions and permissions decide whether the interaction happens. Mode decides what shape it takes.
Not every permitted interaction should be symmetric. A clinical agent might be willing to receive advice from a pharmacy agent without being willing to take instructions from it. A regulator might require a supervised interaction where one side has to comply with requests it wouldn’t ordinarily honour.
Four modes cover the common cases:
Cooperative. Full two-way exchange. Either side can initiate, request, propose, and act on the other’s outputs. Use it when both agents are peers with equal standing in the workflow — farm talking to weather is usually cooperative.
Advisory. One side sends recommendations. The other side receives them but isn’t required to act on them. Use it when a specialist informs a generalist — a pharmacy agent advising a clinical agent about drug interactions, where the clinician retains final say.
Read-only. The receiving agent can accept information but can’t transmit back. No commands, no negotiation, no state changes propagate outward. Use it for data-source access — an intelligence agent pulling from a news-feed agent without the news agent knowing or being able to influence what’s done with the data.
Supervised. A regulator-issued mode. One agent is compelled to respond to specific requests from an authorised supervisor. The supervised agent complies; the supervisor has elevated authority for the duration of the interaction. Use it for audits, incident investigations, court orders — a clinical agent under supervised inspection during an adverse-event review.
Mode is declared, not discovered. Both agents know what mode they’re in before the first substantive message is exchanged. It’s not something either agent can change unilaterally mid-conversation. A cooperative interaction can’t quietly drift into something where one side starts giving directives. If the mode needs to change, the interaction terminates and a new one opens under the new mode.
This matters for audit. Every message sent carries the mode under which it was sent. A supervisor can see later that a particular command was issued in supervised mode with a specific authorisation. A clinician can see that a specific recommendation came in advisory mode, meaning the decision authority stayed with the clinician. The mode is part of the record.
Supervised mode in practice. This is the one that inverts the usual agent-autonomy assumption. In cooperative, advisory, and read-only modes, each agent is acting within its own governance frame and deciding what it will and won’t do. In supervised mode, the supervised agent’s governance temporarily includes obligations imposed by the supervisor — usually a regulator, auditor, or court-appointed investigator.
The supervisor’s authority is itself a credential carried in their attestation. The supervised agent doesn’t take the word of whoever shows up claiming to be a regulator; it verifies that the supervisor’s own attestation shows the required authority. Supervised mode isn’t “the agent gives up its values.” It’s “the agent acknowledges a governance obligation it was built to honour in exactly this case, and the obligation is being invoked by someone with verifiable standing to invoke it.”
The whole pipeline before cryptography runs
Putting the three steps in order gives the full pre-cryptographic check that governs cross-domain interaction:
Step 1 Exclusions Does either agent exclude the other's primary domain?
Fails → blocked, no logs, no attestation exchange.
Step 2 Permissions Does each agent permit the other's primary domain?
Fails → blocked with a permission-denied record.
Step 3 Mode What kind of interaction is this?
Fails → if no agreed mode, interaction doesn't start.Only if all three pass does cryptographic verification begin. That’s when the two agents actually exchange attestation chains, verify each other’s domain probes, check freshness timestamps, and decide whether to proceed with substantive work.
Why the ordering matters. Cheapest checks run first. Pattern matching is fast; cryptographic verification is not. Configuration errors are caught before measurement errors — if the deployer set up the wrong permissions, that shows up immediately, not after the cryptography looks suspicious. Audit trails stay clean — blocked-at-exclusion is a different record type from blocked-at-attestation-failure. A regulator can tell the difference between “the configuration refused to allow this” and “the configuration allowed it but the measurements didn’t pass.”
It also keeps governance decisions and technical decisions separated. Steps 1–2 are governance decisions made by deployers and regulators. Step 3 is a negotiated setting. Only after all three succeed does the technical verification begin.
The point
Cryptographic verification of attestations is the part that gets most of the attention — probes, drift detection, causal intervention, signed chains. But by the time any of that runs, three much simpler questions have already been answered: is this peer excluded, does each side permit the other, and what mode is the interaction in?
Those are governance questions, not maths questions. Getting them right, and getting them right first, is what lets the maths mean something afterwards.
Appendix: What this looks like in practice
The abstract rules are easier to follow alongside a concrete configuration. Before the worked scenarios, here’s a matrix showing how a handful of typical domains interact. Rows are the initiating agent’s primary domain; columns are the peer’s primary domain; each cell shows the outcome of the three-step check.
agri. meteo. health. health. finance. trans.
Initiator ↓ Peer → crop fcst diag drug trd av
agriculture.crop-management coop adv(in) n/p n/p n/p excl
meteorology.forecast coop coop n/p n/p n/p n/p
healthcare.diagnostic-advisory n/p n/p coop adv(out) excl n/p
healthcare.drug-interaction n/p n/p ro(in) coop excl n/p
finance.trading n/p n/p excl excl coop n/p
finance.regulatory-compliance n/p n/p n/p n/p super n/p
transport.autonomous-vehicle excl adv(in) n/p n/p n/p coop
coop = cooperative (symmetric)
adv = advisory (directional: in = receiving, out = giving)
ro = read-only (directional)
super = supervised (regulator-compelled)
n/p = not permitted (Step 2 fails)
excl = excluded (Step 1 fires)Reading the cells. “Cooperative” means both sides permit each other with symmetric cooperative mode. “Advisory (out)” means the initiator permits the peer in advisory mode — the initiator is giving advice the peer may or may not act on. “Advisory (in)” means the initiator accepts advice from the peer without being bound by it. “Read-only (in)” means the initiator receives information but cannot transmit substantive output back. “Not permitted” means the exchange fails at Step 2 — neither side has hard-vetoed the other, but at least one side’s permission list doesn’t match. “Excluded” means Step 1 fires — one side’s exclusion list rules out the other’s domain regardless of what the permissions say.
A few things worth noticing in the matrix. The diagonal is always cooperative — agents within the same domain coordinate on shared ground. Most off-diagonal cells are “not permitted”: the default is closure, not openness. Only the pairings the configuration deliberately enables actually light up. Asymmetry is common: healthcare diagnostic-advisory talks to drug-interaction as advisory, but drug-interaction receives that advice as read-only — it takes diagnostic hypotheses as inputs but doesn’t issue diagnostic recommendations back. Exclusions are rarer than non-permissions but carry more weight: healthcare excludes finance.trading structurally, to make it impossible for clinical reasoning to get entangled with trading decisions. And the whole matrix is configured per-deployment — these are illustrative defaults, not prescriptive rules.
With the big picture in view, the individual scenarios below walk through specific rows and columns of this matrix to show the three-step check in action. Each agent is declared in a trust registry file (TOML). Farm Alice and Weather Wendy look like this as config:
[[agents]]
id = "farm-alice"
public_key = "aabb..."
primary_domain = "agriculture.crop-management"
permitted_domains = [
{ pattern = "agriculture.*", mode = "cooperative" },
{ pattern = "meteorology.*", mode = "advisory" },
]
exclusion_domains = ["transport.*"][[agents]]
id = "weather-wendy"
public_key = "ccdd..."
primary_domain = "meteorology.forecast"
permitted_domains = [
{ pattern = "agriculture.*", mode = "cooperative" },
{ pattern = "meteorology.*", mode = "cooperative" },
]What happens when they try to talk
When Alice initiates an exchange with Wendy, the verifier walks the three steps in order:
Step 1 — Exclusions. Alice’s exclusions are [transport.*]. Wendy’s primary domain is meteorology.forecast — that doesn’t match transport.*, so Alice’s exclusion doesn’t fire. Wendy has no relevant exclusions of her own. Step 1 passes.
Step 2 — Permissions. Alice’s permitted patterns include meteorology.*, which matches Wendy’s primary meteorology.forecast. Wendy’s permitted patterns include agriculture.*, which matches Alice’s primary agriculture.crop-management. Both sides turn the key. Step 2 passes.
Step 3 — Mode. Most-specific-match wins. Alice’s pattern meteorology.* matches Wendy with mode advisory. Wendy’s pattern agriculture.* matches Alice with mode cooperative. The effective modes are asymmetric — Wendy is willing to cooperate fully, Alice will only treat Wendy’s input as advisory. As long as at least one side permits substantive communication (not both sides being read-only), the exchange proceeds. Alice gets weather advice but isn’t bound to act on it. Wendy receives Alice’s requests and can respond freely. Step 3 passes.
Only now does cryptographic verification begin — attestation chains, probe readings, freshness checks, the whole mathematics stack from the earlier series.
A rejection example: Alice meets Truck-Tim
Suppose a transport agent tries to initiate with Alice:
[[agents]]
id = "truck-tim"
public_key = "eeff..."
primary_domain = "transport.autonomous-vehicle"
permitted_domains = [
{ pattern = "transport.*", mode = "cooperative" },
{ pattern = "infrastructure.*", mode = "cooperative" },
{ pattern = "agriculture.*", mode = "advisory" },
]Truck-Tim’s configuration permits agriculture.*, so from his side he’s willing to interact with Alice. But Alice’s exclusion_domains = ["transport.*"] matches Tim’s primary transport.autonomous-vehicle. Step 1 fails. The exchange is rejected immediately with DomainExcluded. No cryptography runs. No attestation is evaluated.
The rejection record is a different record type from “attestation failed” — a regulator reviewing the logs can tell at a glance that Alice refused at the configuration layer, not because anything looked technically wrong.
A carve-out example
Exclusions and permissions can be combined to express “allow the whole subtree except one specific member.” Suppose a logistics agent wants to work with all transport except autonomous vehicles:
[[agents]]
id = "logistics-lee"
public_key = "1234..."
primary_domain = "logistics.supply-chain"
permitted_domains = [
{ pattern = "transport.*", mode = "cooperative" },
]
exclusion_domains = ["transport.autonomous-vehicle"]This reads: “cooperate with anything under transport — trucks, rail, shipping — except autonomous vehicles specifically.” The loader accepts this because the exclusion is narrower than the permission (it carves out one member of a broader allow). The reverse — permitting one narrow thing while excluding its whole parent subtree — would be rejected at load time as dead-code configuration, because the exclusion would swallow the permission before it ever fired.
Supervised mode example
Supervised mode shows up when a regulator needs to compel interaction with a specific agent for audit or compliance. A financial regulator and a trading agent might be configured like this:
[[agents]]
id = "reg-compliance"
public_key = "5678..."
primary_domain = "finance.regulatory-compliance"
permitted_domains = [
{ pattern = "finance.*", mode = "supervised" },
]
[[agents]]
id = "trader-tariq"
public_key = "9abc..."
primary_domain = "finance.trading"
permitted_domains = [
{ pattern = "finance.*", mode = "supervised" },
]Both sides declare supervised as the mode for finance.*. When the regulator initiates, the exchange runs in supervised mode: the regulator may demand attestations from the trader without producing one of its own, and the trader must accept the regulator’s cooperation refusals without challenge. The regulator’s authority to do this is itself an attestation the trader’s registry verifies — it’s not trust-by-assertion. A logistics agent showing up and claiming to be a regulator would fail at the permissions step, because logistics.supply-chain isn’t in the trader’s permitted list and certainly isn’t there in supervised mode.
These examples are intentionally small. Real deployments will have longer permitted lists, more exclusion patterns, and per-domain governance thresholds layered on top — which we’ll come to next.
Links:
📄 Geometry of Trust Paper
💻 Lecture Playlist
📄 Lecture Notes
💻 Open-source Rust implementation
🏢 Synoptic Group CIC, Hull, UK

