Counterparty depth
The per-(action class × counterparty) trust graph is Cortex's moat. The counterparty depth surface exposes that graph as a callable API so your app renders trust posture, prior interactions, and inferred classification natively — instead of guessing from raw message history.
The five tools
counterparty.profile(counterparty_id)— the identity-resolved record + trust pairs across action classes + recent activity + plain-language summary.counterparty.list(filter)— paginated enumeration with filters by entity_type, trust-pair minimum, free-text query.counterparty.activity(counterparty_id, since?, until?)— episodes + recent actions in a time window.counterparty.classify(counterparty_id)— inferred relationship + class (colleague / family / vendor / friend / unknown) with confidence + plain-language evidence summary.trust.posture(counterparty_id, action_class?)— per-(action class × counterparty) trust level + survival metric + recent trajectory (graduating/stable/demoted).
Why this is the moat surface
The PRD has long claimed “per-user accumulated context” as Cortex's moat. Until this surface, that claim sat in marketing copy with no API to verify it. The five tools above are the verification: any builder can query the trust graph, observe the compounding state over time, and render it natively in their UI.
No competitor structurally has this. All surveyed agent-governance products track trust per agent or per tenant, not per-user across multiple apps and per per-(action class × counterparty) within each app. The shape of the data is the differentiation.
Example: rendering a conversation header with trust context
// User opens a message thread with Sarah in your app
const [profile, posture] = await Promise.all([
cortex.tools.call('counterparty.profile', { counterparty_id: 'entity_01HXSARAH' }),
cortex.tools.call('trust.posture', {
counterparty_id: 'entity_01HXSARAH',
action_class: 'communicate',
}),
]);
return (
<ConversationHeader>
<DisplayName>{profile.display_name}</DisplayName>
<Relationship>{profile.relationship}</Relationship>
<TrustPosture
level={posture.pairs[0]?.autonomy_level ?? 1}
survivalRate={posture.pairs[0]?.trust_survival_rate}
trajectory={posture.pairs[0]?.recent_trajectory}
/>
<RecentSummary>{profile.recent_summary}</RecentSummary>
</ConversationHeader>
);Entity-type pluggability
Every tool here accepts an optional entity_type parameter (default 'person') per ADR-0018. A finance customer registering account as an entity type can call counterparty.profile({ counterparty_id, entity_type: 'account' }) and get the same shape of response — trust pairs across action classes, recent activity, classification — for a non-person counterparty. The substrate is type-pluggable; the API is uniform.
Quota
Read calls count against daily_substrate_read_calls (separate from action calls). See rate limits & quotas for current defaults.
Cross-references
- Concept: Explainability — pairs naturally for “why this counterparty trust state?” reasoning.
- Concept: Commitments — per-counterparty commitment tracking ties into the same graph.
- ADR-0021 §read-API (Family B — Counterparty Depth), ADR-0018 (entity-type pluggability).