@indexnetwork/protocol 6.15.0-rc.407.1 → 8.0.1-rc.417.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +302 -0
- package/IMPLEMENTATION.md +7 -4
- package/dist/capabilities/opportunities.facade.d.ts +4 -0
- package/dist/capabilities/opportunities.facade.js +4 -0
- package/dist/chat/chat-streaming.types.d.ts +4 -5
- package/dist/chat/chat.agent.d.ts +0 -19
- package/dist/chat/chat.agent.js +1 -70
- package/dist/chat/chat.persona.d.ts +0 -6
- package/dist/chat/chat.persona.js +0 -1
- package/dist/chat/chat.prompt.js +10 -10
- package/dist/chat/chat.prompt.modules.js +0 -104
- package/dist/chat/chat.tools.js +11 -7
- package/dist/chat/negotiator.persona.js +0 -1
- package/dist/chat/onboarding.persona.js +0 -1
- package/dist/chat/reporter.persona.d.ts +1 -1
- package/dist/chat/reporter.persona.js +1 -2
- package/dist/chat/reporter.prompt.js +5 -5
- package/dist/chat/signal.persona.js +0 -1
- package/dist/communities/application/network.tools.js +48 -27
- package/dist/contacts/application/contact.tools.js +9 -9
- package/dist/index.d.ts +9 -2
- package/dist/index.js +5 -0
- package/dist/maintenance/maintenance.graph.js +7 -0
- package/dist/mcp/mcp.authorization-policy.d.ts +250 -0
- package/dist/mcp/mcp.authorization-policy.js +522 -0
- package/dist/mcp/mcp.server.d.ts +6 -29
- package/dist/mcp/mcp.server.js +202 -228
- package/dist/negotiation/application/negotiation.agent.js +29 -5
- package/dist/negotiation/application/negotiation.graph.d.ts +2 -5
- package/dist/negotiation/application/negotiation.graph.js +53 -23
- package/dist/negotiation/domain/index.d.ts +3 -0
- package/dist/negotiation/domain/index.js +3 -0
- package/dist/negotiation/domain/negotiation.deadlock.d.ts +7 -1
- package/dist/negotiation/domain/negotiation.deadlock.js +48 -1
- package/dist/negotiation/domain/negotiation.stance.contracts.d.ts +85 -0
- package/dist/negotiation/domain/negotiation.stance.contracts.js +140 -0
- package/dist/negotiation/domain/negotiation.state.d.ts +2 -3
- package/dist/negotiation/domain/negotiation.state.js +2 -3
- package/dist/negotiation/public/index.d.ts +2 -0
- package/dist/negotiation/public/index.js +2 -0
- package/dist/opportunity/application/index.d.ts +0 -3
- package/dist/opportunity/application/index.js +0 -3
- package/dist/opportunity/application/opportunity.graph.d.ts +0 -43
- package/dist/opportunity/application/opportunity.graph.js +7 -113
- package/dist/opportunity/application/opportunity.introducer-feature.d.ts +2 -0
- package/dist/opportunity/application/opportunity.introducer-feature.js +4 -0
- package/dist/opportunity/application/opportunity.owner-approval.d.ts +118 -0
- package/dist/opportunity/application/opportunity.owner-approval.js +34 -0
- package/dist/opportunity/application/opportunity.owner-provenance.d.ts +6 -0
- package/dist/opportunity/application/opportunity.owner-provenance.js +28 -0
- package/dist/opportunity/application/opportunity.tools.d.ts +3 -3
- package/dist/opportunity/application/opportunity.tools.js +77 -870
- package/dist/opportunity/discriminator/discriminator.shadow.js +17 -10
- package/dist/opportunity/discriminator/discriminator.types.d.ts +2 -0
- package/dist/opportunity/domain/index.d.ts +0 -2
- package/dist/opportunity/domain/index.js +0 -2
- package/dist/opportunity/domain/opportunity.state.d.ts +2 -70
- package/dist/opportunity/domain/opportunity.state.js +2 -55
- package/dist/opportunity/opportunity.owner-approval.d.ts +5 -0
- package/dist/opportunity/opportunity.owner-approval.js +5 -0
- package/dist/opportunity/ports/opportunity.tools.port.d.ts +12 -1
- package/dist/opportunity/public/index.d.ts +3 -3
- package/dist/opportunity/public/index.js +2 -1
- package/dist/participant-agents/application/agent.tools.d.ts +1 -1
- package/dist/participant-agents/application/agent.tools.js +44 -6
- package/dist/participant-agents/application/index.d.ts +5 -3
- package/dist/participant-agents/application/index.js +5 -3
- package/dist/questions/application/question.tools.js +31 -2
- package/dist/runtime/foreground/composition/tool.factory.d.ts +2 -1
- package/dist/runtime/foreground/composition/tool.factory.js +9 -2
- package/dist/runtime/foreground/composition/tool.registry.d.ts +16 -2
- package/dist/runtime/foreground/composition/tool.registry.js +41 -38
- package/dist/shared/agent/activity-projection.d.ts +271 -0
- package/dist/shared/agent/activity-projection.js +248 -0
- package/dist/shared/agent/canonical-guidance.d.ts +30 -0
- package/dist/shared/agent/canonical-guidance.js +249 -0
- package/dist/shared/agent/tool.helpers.d.ts +9 -17
- package/dist/shared/agent/tool.runtime.js +1 -3
- package/dist/shared/agent/utility.tools.d.ts +11 -1
- package/dist/shared/agent/utility.tools.js +126 -90
- package/dist/shared/interfaces/auth.interface.d.ts +2 -8
- package/dist/shared/interfaces/chat-session.interface.js +5 -0
- package/dist/shared/interfaces/database.interface.d.ts +12 -5
- package/dist/shared/observability/request-context.d.ts +4 -40
- package/dist/shared/schemas/mcp-auth.schema.d.ts +87 -15
- package/dist/shared/schemas/mcp-auth.schema.js +49 -1
- package/dist/signals/application/intent.tools.js +7 -8
- package/package.json +10 -9
- package/dist/opportunity/application/opportunity.discover.d.ts +0 -215
- package/dist/opportunity/application/opportunity.discover.js +0 -793
- package/dist/opportunity/application/opportunity.discovery-continuation-finalization.d.ts +0 -34
- package/dist/opportunity/application/opportunity.discovery-continuation-finalization.js +0 -74
- package/dist/opportunity/application/opportunity.discovery-mcp-lifecycle-finalization.d.ts +0 -44
- package/dist/opportunity/application/opportunity.discovery-mcp-lifecycle-finalization.js +0 -92
- package/dist/opportunity/domain/opportunity.discovery-run-coalescing.d.ts +0 -33
- package/dist/opportunity/domain/opportunity.discovery-run-coalescing.js +0 -33
- package/dist/opportunity/domain/opportunity.discovery.contracts.d.ts +0 -45
- package/dist/opportunity/domain/opportunity.discovery.contracts.js +0 -1
- package/dist/opportunity/opportunity.discover.d.ts +0 -5
- package/dist/opportunity/opportunity.discover.js +0 -5
- package/dist/opportunity/opportunity.discovery-continuation-finalization.d.ts +0 -5
- package/dist/opportunity/opportunity.discovery-continuation-finalization.js +0 -5
- package/dist/opportunity/opportunity.discovery-mcp-lifecycle-finalization.d.ts +0 -5
- package/dist/opportunity/opportunity.discovery-mcp-lifecycle-finalization.js +0 -5
- package/dist/opportunity/opportunity.discovery-run-coalescing.d.ts +0 -5
- package/dist/opportunity/opportunity.discovery-run-coalescing.js +0 -5
- package/dist/opportunity/opportunity.discovery.contracts.d.ts +0 -5
- package/dist/opportunity/opportunity.discovery.contracts.js +0 -5
- package/dist/shared/interfaces/discovery-run.interface.d.ts +0 -70
- package/dist/shared/interfaces/discovery-run.interface.js +0 -1
|
@@ -14,17 +14,9 @@ import { createQuestionerTools } from '../../../capabilities/questions.facade.js
|
|
|
14
14
|
import { protocolLogger } from '../../../shared/observability/protocol.logger.js';
|
|
15
15
|
import { requestContext } from '../../../shared/observability/request-context.js';
|
|
16
16
|
const logger = protocolLogger('ToolRegistry');
|
|
17
|
-
|
|
18
|
-
* Creates a tool registry containing all tool handlers indexed by name.
|
|
19
|
-
* Handlers are raw async functions (not LangChain tool() wrappers) that
|
|
20
|
-
* accept { context, query } and return a JSON string.
|
|
21
|
-
*
|
|
22
|
-
* @param deps - Shared tool dependencies (graphs, database, embedder, etc.)
|
|
23
|
-
* @param context - Resolved user context for this request.
|
|
24
|
-
* @returns Map of tool name to raw tool definition.
|
|
25
|
-
*/
|
|
26
|
-
export function createToolRegistry(deps) {
|
|
17
|
+
export function createToolRegistry(deps, options = {}) {
|
|
27
18
|
const registry = new Map();
|
|
19
|
+
const isMcpSurface = options.surface === 'mcp';
|
|
28
20
|
// defineTool that captures raw handlers into the registry
|
|
29
21
|
function defineTool(opts) {
|
|
30
22
|
const entry = {
|
|
@@ -65,9 +57,17 @@ export function createToolRegistry(deps) {
|
|
|
65
57
|
createIntentTools(dt, deps);
|
|
66
58
|
createNetworkTools(dt, deps);
|
|
67
59
|
createOpportunityTools(dt, deps);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
// Utility tools always register read_docs + read_activity_summary; on the
|
|
61
|
+
// MCP surface scrape_url is omitted and read_docs guidance is sanitized
|
|
62
|
+
// (IND-597). The retired report_agent_activity name retains no alias on
|
|
63
|
+
// either surface (IND-605).
|
|
64
|
+
createUtilityTools(dt, deps, { surface: isMcpSurface ? 'mcp' : 'rest' });
|
|
65
|
+
// Contact/Gmail import tools are omitted from the MCP surface (IND-596). Their
|
|
66
|
+
// implementations remain available to the REST Tool API and chat agent.
|
|
67
|
+
if (!isMcpSurface) {
|
|
68
|
+
createIntegrationTools(dt, deps);
|
|
69
|
+
createContactTools(dt, deps);
|
|
70
|
+
}
|
|
71
71
|
createAgentTools(dt, deps);
|
|
72
72
|
createNegotiationTools(dt, deps);
|
|
73
73
|
createPremiseTools(dt, deps);
|
|
@@ -75,32 +75,35 @@ export function createToolRegistry(deps) {
|
|
|
75
75
|
if (deps.chatSession) {
|
|
76
76
|
createChatTools(dt, deps);
|
|
77
77
|
}
|
|
78
|
-
// Deprecated tool-name aliases (IND-371). The canonical implementations are
|
|
79
|
-
// registered under their *_user_context / *_enrichment_run names;
|
|
80
|
-
//
|
|
81
|
-
// exact same handler + schema
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
[
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
78
|
+
// Deprecated tool-name aliases (IND-371). The canonical implementations are
|
|
79
|
+
// registered under their *_user_context / *_enrichment_run names; the legacy
|
|
80
|
+
// *_user_profile / *_profile_run names are retained as thin aliases that
|
|
81
|
+
// delegate to the exact same handler + schema so existing direct HTTP Tool
|
|
82
|
+
// API clients keep working. These aliases are NOT exposed on the MCP surface
|
|
83
|
+
// (IND-598) — MCP callers must use the canonical names.
|
|
84
|
+
if (!isMcpSurface) {
|
|
85
|
+
const DEPRECATED_TOOL_ALIASES = [
|
|
86
|
+
["read_user_profiles", "read_user_contexts"],
|
|
87
|
+
["create_user_profile", "create_user_context"],
|
|
88
|
+
["update_user_profile", "update_user_context"],
|
|
89
|
+
["confirm_user_profile", "confirm_user_context"],
|
|
90
|
+
["preview_user_profile", "preview_user_context"],
|
|
91
|
+
["get_profile_run", "get_enrichment_run"],
|
|
92
|
+
["cancel_profile_run", "cancel_enrichment_run"],
|
|
93
|
+
];
|
|
94
|
+
for (const [oldName, canonicalName] of DEPRECATED_TOOL_ALIASES) {
|
|
95
|
+
const canonical = registry.get(canonicalName);
|
|
96
|
+
if (!canonical) {
|
|
97
|
+
logger.warn('Cannot register deprecated alias: canonical tool not found', { alias: oldName, canonicalName });
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
registry.set(oldName, {
|
|
101
|
+
...canonical,
|
|
102
|
+
name: oldName,
|
|
103
|
+
description: `[DEPRECATED — use \`${canonicalName}\` instead; this alias is retained for backward compatibility and will be removed.] ${canonical.description}`,
|
|
104
|
+
});
|
|
97
105
|
}
|
|
98
|
-
registry.set(oldName, {
|
|
99
|
-
...canonical,
|
|
100
|
-
name: oldName,
|
|
101
|
-
description: `[DEPRECATED — use \`${canonicalName}\` instead; this alias is retained for backward compatibility and will be removed.] ${canonical.description}`,
|
|
102
|
-
});
|
|
103
106
|
}
|
|
104
|
-
logger.verbose('Tool registry created', { toolCount: registry.size });
|
|
107
|
+
logger.verbose('Tool registry created', { toolCount: registry.size, surface: options.surface ?? 'rest' });
|
|
105
108
|
return registry;
|
|
106
109
|
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AgentActivitySummary } from "../interfaces/database.interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* Centralized activity-summary permission projection (IND-605).
|
|
5
|
+
*
|
|
6
|
+
* `read_activity_summary` is the only public name for grounded, aggregate-only
|
|
7
|
+
* agent activity reporting. The handler passes a typed resolved caller context
|
|
8
|
+
* into this one projection:
|
|
9
|
+
*
|
|
10
|
+
* - Human owners (REST/chat surfaces and session-authenticated MCP callers)
|
|
11
|
+
* receive every domain.
|
|
12
|
+
* - Registered agents receive only the domains their permissions authorize.
|
|
13
|
+
* Signal IDs/titles (`opportunitiesBySignal`) require `manage:intents`.
|
|
14
|
+
* - Question counts are meta-network: they are never narrowed by a network
|
|
15
|
+
* binding, but each count inherits the permission of the domain the
|
|
16
|
+
* question AFFECTS. A caller sees a domain's question counts only when it
|
|
17
|
+
* holds that domain's permission; conversational (`chat`-mode) and
|
|
18
|
+
* unrecognized modes are human-owner-only. There is deliberately no
|
|
19
|
+
* any-of all-question count shortcut.
|
|
20
|
+
* - Network agents additionally narrow network-bound aggregates to their bound
|
|
21
|
+
* community — exposed here as `activitySummaryNetworkId` so the narrowing
|
|
22
|
+
* happens in the query/adapter layer, never as transport-local JSON
|
|
23
|
+
* filtering.
|
|
24
|
+
*
|
|
25
|
+
* The projection can only drop fields. It never fabricates data and it never
|
|
26
|
+
* exposes counterparty identities, chats, turns, transcripts, or private
|
|
27
|
+
* content; the strict response schema below is the explicit output contract.
|
|
28
|
+
*/
|
|
29
|
+
/** Canonical public tool name for aggregate activity reporting. */
|
|
30
|
+
export declare const READ_ACTIVITY_SUMMARY_TOOL_NAME = "read_activity_summary";
|
|
31
|
+
/** Activity summary domains, in stable projection order. */
|
|
32
|
+
export declare const ActivitySummaryDomainSchema: z.ZodEnum<["signals", "opportunities", "questions", "negotiations"]>;
|
|
33
|
+
export type ActivitySummaryDomain = z.infer<typeof ActivitySummaryDomainSchema>;
|
|
34
|
+
/**
|
|
35
|
+
* Domains a question can affect. `'chat'` covers conversational questions
|
|
36
|
+
* (and, fail-closed, any mode added to the protocol enum later): they have no
|
|
37
|
+
* agent-permission domain and are visible to human owners only.
|
|
38
|
+
*/
|
|
39
|
+
export declare const ActivityQuestionDomainSchema: z.ZodEnum<["identity", "premises", "intents", "opportunities", "negotiations", "chat"]>;
|
|
40
|
+
export type ActivityQuestionDomain = z.infer<typeof ActivityQuestionDomainSchema>;
|
|
41
|
+
/**
|
|
42
|
+
* Maps every current `QuestionMode` to the domain the question affects.
|
|
43
|
+
* Modes missing from this table fail closed to the human-only `'chat'`
|
|
44
|
+
* bucket so a future protocol mode can never leak to an agent caller.
|
|
45
|
+
*/
|
|
46
|
+
export declare const QUESTION_MODE_TO_DOMAIN: Readonly<Record<string, ActivityQuestionDomain>>;
|
|
47
|
+
/**
|
|
48
|
+
* Explicit per-domain question counts. Each key is present only when the
|
|
49
|
+
* caller is authorized for that domain and the count is non-zero.
|
|
50
|
+
*/
|
|
51
|
+
export declare const ActivityQuestionCountsSchema: z.ZodObject<{
|
|
52
|
+
identity: z.ZodOptional<z.ZodNumber>;
|
|
53
|
+
premises: z.ZodOptional<z.ZodNumber>;
|
|
54
|
+
intents: z.ZodOptional<z.ZodNumber>;
|
|
55
|
+
opportunities: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
negotiations: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
/** Human-owner-only conversational (or unrecognized) question counts. */
|
|
58
|
+
chat: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
}, "strict", z.ZodTypeAny, {
|
|
60
|
+
chat?: number | undefined;
|
|
61
|
+
identity?: number | undefined;
|
|
62
|
+
intents?: number | undefined;
|
|
63
|
+
premises?: number | undefined;
|
|
64
|
+
opportunities?: number | undefined;
|
|
65
|
+
negotiations?: number | undefined;
|
|
66
|
+
}, {
|
|
67
|
+
chat?: number | undefined;
|
|
68
|
+
identity?: number | undefined;
|
|
69
|
+
intents?: number | undefined;
|
|
70
|
+
premises?: number | undefined;
|
|
71
|
+
opportunities?: number | undefined;
|
|
72
|
+
negotiations?: number | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
export type ActivityQuestionCounts = z.infer<typeof ActivityQuestionCountsSchema>;
|
|
75
|
+
/**
|
|
76
|
+
* Typed resolved MCP caller context consumed by the projection. Derived from
|
|
77
|
+
* the MCP capability subject at the transport boundary (see
|
|
78
|
+
* `resolveMcpActivityCaller` in mcp.authorization-policy.ts); absent on
|
|
79
|
+
* REST/chat surfaces, which are owner-trusted.
|
|
80
|
+
*/
|
|
81
|
+
export declare const McpActivityCallerSchema: z.ZodObject<{
|
|
82
|
+
/** `'human'` callers own the summarized data and see every domain. */
|
|
83
|
+
kind: z.ZodEnum<["human", "agent"]>;
|
|
84
|
+
/** Canonical `manage:*` permission actions granted to the caller. */
|
|
85
|
+
permissions: z.ZodArray<z.ZodString, "many">;
|
|
86
|
+
/** A network agent's bound community; always null for humans. */
|
|
87
|
+
networkScopeId: z.ZodNullable<z.ZodString>;
|
|
88
|
+
}, "strict", z.ZodTypeAny, {
|
|
89
|
+
kind: "human" | "agent";
|
|
90
|
+
permissions: string[];
|
|
91
|
+
networkScopeId: string | null;
|
|
92
|
+
}, {
|
|
93
|
+
kind: "human" | "agent";
|
|
94
|
+
permissions: string[];
|
|
95
|
+
networkScopeId: string | null;
|
|
96
|
+
}>;
|
|
97
|
+
export type McpActivityCaller = z.infer<typeof McpActivityCallerSchema>;
|
|
98
|
+
/**
|
|
99
|
+
* Canonical affected-domain permission an agent must hold to read or answer a
|
|
100
|
+
* question of the given mode. Returns `null` for human-owner-only questions
|
|
101
|
+
* (`chat`, and any unrecognized mode, which fail closed to the human-only
|
|
102
|
+
* bucket) — no agent permission can release those.
|
|
103
|
+
*
|
|
104
|
+
* This is the single shared mode → affected-domain → permission mapping, reusing
|
|
105
|
+
* `QUESTION_MODE_TO_DOMAIN` and `QUESTION_DOMAIN_PERMISSIONS` so question
|
|
106
|
+
* read/answer inheritance is identical to the `read_activity_summary`
|
|
107
|
+
* projection. It keys on `mode` only: the canonical question model does not vary
|
|
108
|
+
* a question's owning domain by `purpose` (purpose refines generation and
|
|
109
|
+
* provenance, not the affected domain), so purpose is intentionally not a
|
|
110
|
+
* discriminant here rather than being guessed at.
|
|
111
|
+
*/
|
|
112
|
+
export declare function questionModeRequiredPermission(mode: string): string | null;
|
|
113
|
+
/**
|
|
114
|
+
* Whether an MCP caller may read or answer a question of the given mode. Human
|
|
115
|
+
* (owner) callers see every mode; agents are confined to modes backed by one of
|
|
116
|
+
* their exact affected-domain permissions. A network agent's binding is applied
|
|
117
|
+
* separately by the caller (network/intent clamp); this is purely the
|
|
118
|
+
* affected-domain permission gate.
|
|
119
|
+
*/
|
|
120
|
+
export declare function callerMayAccessQuestionMode(caller: McpActivityCaller, mode: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Explicit response contract for `read_activity_summary`. Every domain field
|
|
123
|
+
* is optional because agent callers receive only their authorized domains.
|
|
124
|
+
* Strict: no counterparty or unspecified field can pass validation.
|
|
125
|
+
*/
|
|
126
|
+
export declare const ActivitySummaryResponseSchema: z.ZodObject<{
|
|
127
|
+
/** The reporting window actually used, in hours. */
|
|
128
|
+
sinceHours: z.ZodNumber;
|
|
129
|
+
/** signals domain — liveSignalsWatched and per-signal opportunity counts. */
|
|
130
|
+
liveSignalsWatched: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
/** opportunities domain. */
|
|
132
|
+
opportunitiesSurfaced: z.ZodOptional<z.ZodNumber>;
|
|
133
|
+
/** signals domain — signal IDs/titles, authorized by manage:intents only. */
|
|
134
|
+
opportunitiesBySignal: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
135
|
+
intentId: z.ZodString;
|
|
136
|
+
title: z.ZodString;
|
|
137
|
+
count: z.ZodNumber;
|
|
138
|
+
}, "strict", z.ZodTypeAny, {
|
|
139
|
+
title: string;
|
|
140
|
+
intentId: string;
|
|
141
|
+
count: number;
|
|
142
|
+
}, {
|
|
143
|
+
title: string;
|
|
144
|
+
intentId: string;
|
|
145
|
+
count: number;
|
|
146
|
+
}>, "many">>;
|
|
147
|
+
/** questions domain (meta-network) — counts grouped by affected domain. */
|
|
148
|
+
pendingQuestionsByDomain: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
identity: z.ZodOptional<z.ZodNumber>;
|
|
150
|
+
premises: z.ZodOptional<z.ZodNumber>;
|
|
151
|
+
intents: z.ZodOptional<z.ZodNumber>;
|
|
152
|
+
opportunities: z.ZodOptional<z.ZodNumber>;
|
|
153
|
+
negotiations: z.ZodOptional<z.ZodNumber>;
|
|
154
|
+
/** Human-owner-only conversational (or unrecognized) question counts. */
|
|
155
|
+
chat: z.ZodOptional<z.ZodNumber>;
|
|
156
|
+
}, "strict", z.ZodTypeAny, {
|
|
157
|
+
chat?: number | undefined;
|
|
158
|
+
identity?: number | undefined;
|
|
159
|
+
intents?: number | undefined;
|
|
160
|
+
premises?: number | undefined;
|
|
161
|
+
opportunities?: number | undefined;
|
|
162
|
+
negotiations?: number | undefined;
|
|
163
|
+
}, {
|
|
164
|
+
chat?: number | undefined;
|
|
165
|
+
identity?: number | undefined;
|
|
166
|
+
intents?: number | undefined;
|
|
167
|
+
premises?: number | undefined;
|
|
168
|
+
opportunities?: number | undefined;
|
|
169
|
+
negotiations?: number | undefined;
|
|
170
|
+
}>>;
|
|
171
|
+
answeredQuestionsByDomain: z.ZodOptional<z.ZodObject<{
|
|
172
|
+
identity: z.ZodOptional<z.ZodNumber>;
|
|
173
|
+
premises: z.ZodOptional<z.ZodNumber>;
|
|
174
|
+
intents: z.ZodOptional<z.ZodNumber>;
|
|
175
|
+
opportunities: z.ZodOptional<z.ZodNumber>;
|
|
176
|
+
negotiations: z.ZodOptional<z.ZodNumber>;
|
|
177
|
+
/** Human-owner-only conversational (or unrecognized) question counts. */
|
|
178
|
+
chat: z.ZodOptional<z.ZodNumber>;
|
|
179
|
+
}, "strict", z.ZodTypeAny, {
|
|
180
|
+
chat?: number | undefined;
|
|
181
|
+
identity?: number | undefined;
|
|
182
|
+
intents?: number | undefined;
|
|
183
|
+
premises?: number | undefined;
|
|
184
|
+
opportunities?: number | undefined;
|
|
185
|
+
negotiations?: number | undefined;
|
|
186
|
+
}, {
|
|
187
|
+
chat?: number | undefined;
|
|
188
|
+
identity?: number | undefined;
|
|
189
|
+
intents?: number | undefined;
|
|
190
|
+
premises?: number | undefined;
|
|
191
|
+
opportunities?: number | undefined;
|
|
192
|
+
negotiations?: number | undefined;
|
|
193
|
+
}>>;
|
|
194
|
+
/** negotiations domain. */
|
|
195
|
+
negotiationsStarted: z.ZodOptional<z.ZodNumber>;
|
|
196
|
+
negotiationsCompleted: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
}, "strict", z.ZodTypeAny, {
|
|
198
|
+
sinceHours: number;
|
|
199
|
+
liveSignalsWatched?: number | undefined;
|
|
200
|
+
opportunitiesSurfaced?: number | undefined;
|
|
201
|
+
opportunitiesBySignal?: {
|
|
202
|
+
title: string;
|
|
203
|
+
intentId: string;
|
|
204
|
+
count: number;
|
|
205
|
+
}[] | undefined;
|
|
206
|
+
pendingQuestionsByDomain?: {
|
|
207
|
+
chat?: number | undefined;
|
|
208
|
+
identity?: number | undefined;
|
|
209
|
+
intents?: number | undefined;
|
|
210
|
+
premises?: number | undefined;
|
|
211
|
+
opportunities?: number | undefined;
|
|
212
|
+
negotiations?: number | undefined;
|
|
213
|
+
} | undefined;
|
|
214
|
+
answeredQuestionsByDomain?: {
|
|
215
|
+
chat?: number | undefined;
|
|
216
|
+
identity?: number | undefined;
|
|
217
|
+
intents?: number | undefined;
|
|
218
|
+
premises?: number | undefined;
|
|
219
|
+
opportunities?: number | undefined;
|
|
220
|
+
negotiations?: number | undefined;
|
|
221
|
+
} | undefined;
|
|
222
|
+
negotiationsStarted?: number | undefined;
|
|
223
|
+
negotiationsCompleted?: number | undefined;
|
|
224
|
+
}, {
|
|
225
|
+
sinceHours: number;
|
|
226
|
+
liveSignalsWatched?: number | undefined;
|
|
227
|
+
opportunitiesSurfaced?: number | undefined;
|
|
228
|
+
opportunitiesBySignal?: {
|
|
229
|
+
title: string;
|
|
230
|
+
intentId: string;
|
|
231
|
+
count: number;
|
|
232
|
+
}[] | undefined;
|
|
233
|
+
pendingQuestionsByDomain?: {
|
|
234
|
+
chat?: number | undefined;
|
|
235
|
+
identity?: number | undefined;
|
|
236
|
+
intents?: number | undefined;
|
|
237
|
+
premises?: number | undefined;
|
|
238
|
+
opportunities?: number | undefined;
|
|
239
|
+
negotiations?: number | undefined;
|
|
240
|
+
} | undefined;
|
|
241
|
+
answeredQuestionsByDomain?: {
|
|
242
|
+
chat?: number | undefined;
|
|
243
|
+
identity?: number | undefined;
|
|
244
|
+
intents?: number | undefined;
|
|
245
|
+
premises?: number | undefined;
|
|
246
|
+
opportunities?: number | undefined;
|
|
247
|
+
negotiations?: number | undefined;
|
|
248
|
+
} | undefined;
|
|
249
|
+
negotiationsStarted?: number | undefined;
|
|
250
|
+
negotiationsCompleted?: number | undefined;
|
|
251
|
+
}>;
|
|
252
|
+
export type ProjectedActivitySummary = z.infer<typeof ActivitySummaryResponseSchema>;
|
|
253
|
+
/**
|
|
254
|
+
* Resolves the summary domains a caller may see. Human owners receive every
|
|
255
|
+
* domain; agents receive only domains backed by one of their permissions.
|
|
256
|
+
* The `questions` domain only flags that at least one affected-domain count
|
|
257
|
+
* may be visible — each count is still filtered per affected domain in
|
|
258
|
+
* `projectActivitySummary`.
|
|
259
|
+
*/
|
|
260
|
+
export declare function resolveActivitySummaryDomains(caller: McpActivityCaller): ActivitySummaryDomain[];
|
|
261
|
+
/**
|
|
262
|
+
* Returns the bound community a network agent's network-bound aggregates must
|
|
263
|
+
* be narrowed to in the query/adapter layer. Undefined for human callers and
|
|
264
|
+
* global agents, whose aggregates span the owner's networks.
|
|
265
|
+
*/
|
|
266
|
+
export declare function activitySummaryNetworkId(caller: McpActivityCaller): string | undefined;
|
|
267
|
+
/**
|
|
268
|
+
* Projects a full owner-scoped summary down to the caller's authorized
|
|
269
|
+
* domains. Pure field selection — no data is transformed or fabricated.
|
|
270
|
+
*/
|
|
271
|
+
export declare function projectActivitySummary(caller: McpActivityCaller, summary: AgentActivitySummary): ProjectedActivitySummary;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Centralized activity-summary permission projection (IND-605).
|
|
4
|
+
*
|
|
5
|
+
* `read_activity_summary` is the only public name for grounded, aggregate-only
|
|
6
|
+
* agent activity reporting. The handler passes a typed resolved caller context
|
|
7
|
+
* into this one projection:
|
|
8
|
+
*
|
|
9
|
+
* - Human owners (REST/chat surfaces and session-authenticated MCP callers)
|
|
10
|
+
* receive every domain.
|
|
11
|
+
* - Registered agents receive only the domains their permissions authorize.
|
|
12
|
+
* Signal IDs/titles (`opportunitiesBySignal`) require `manage:intents`.
|
|
13
|
+
* - Question counts are meta-network: they are never narrowed by a network
|
|
14
|
+
* binding, but each count inherits the permission of the domain the
|
|
15
|
+
* question AFFECTS. A caller sees a domain's question counts only when it
|
|
16
|
+
* holds that domain's permission; conversational (`chat`-mode) and
|
|
17
|
+
* unrecognized modes are human-owner-only. There is deliberately no
|
|
18
|
+
* any-of all-question count shortcut.
|
|
19
|
+
* - Network agents additionally narrow network-bound aggregates to their bound
|
|
20
|
+
* community — exposed here as `activitySummaryNetworkId` so the narrowing
|
|
21
|
+
* happens in the query/adapter layer, never as transport-local JSON
|
|
22
|
+
* filtering.
|
|
23
|
+
*
|
|
24
|
+
* The projection can only drop fields. It never fabricates data and it never
|
|
25
|
+
* exposes counterparty identities, chats, turns, transcripts, or private
|
|
26
|
+
* content; the strict response schema below is the explicit output contract.
|
|
27
|
+
*/
|
|
28
|
+
/** Canonical public tool name for aggregate activity reporting. */
|
|
29
|
+
export const READ_ACTIVITY_SUMMARY_TOOL_NAME = "read_activity_summary";
|
|
30
|
+
/** Activity summary domains, in stable projection order. */
|
|
31
|
+
export const ActivitySummaryDomainSchema = z.enum([
|
|
32
|
+
"signals",
|
|
33
|
+
"opportunities",
|
|
34
|
+
"questions",
|
|
35
|
+
"negotiations",
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Domains a question can affect. `'chat'` covers conversational questions
|
|
39
|
+
* (and, fail-closed, any mode added to the protocol enum later): they have no
|
|
40
|
+
* agent-permission domain and are visible to human owners only.
|
|
41
|
+
*/
|
|
42
|
+
export const ActivityQuestionDomainSchema = z.enum([
|
|
43
|
+
"identity",
|
|
44
|
+
"premises",
|
|
45
|
+
"intents",
|
|
46
|
+
"opportunities",
|
|
47
|
+
"negotiations",
|
|
48
|
+
"chat",
|
|
49
|
+
]);
|
|
50
|
+
/**
|
|
51
|
+
* Maps every current `QuestionMode` to the domain the question affects.
|
|
52
|
+
* Modes missing from this table fail closed to the human-only `'chat'`
|
|
53
|
+
* bucket so a future protocol mode can never leak to an agent caller.
|
|
54
|
+
*/
|
|
55
|
+
export const QUESTION_MODE_TO_DOMAIN = {
|
|
56
|
+
// Enrichment answers run the PremiseGraph lifecycle (createPremiseFromAnswer →
|
|
57
|
+
// PremiseEvents.onCreated), so enrichment questions affect the premises domain.
|
|
58
|
+
enrichment: "premises",
|
|
59
|
+
intent: "intents",
|
|
60
|
+
discovery: "opportunities",
|
|
61
|
+
pool_discovery: "opportunities",
|
|
62
|
+
negotiation: "negotiations",
|
|
63
|
+
negotiation_inflight: "negotiations",
|
|
64
|
+
chat: "chat",
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Explicit per-domain question counts. Each key is present only when the
|
|
68
|
+
* caller is authorized for that domain and the count is non-zero.
|
|
69
|
+
*/
|
|
70
|
+
export const ActivityQuestionCountsSchema = z.object({
|
|
71
|
+
identity: z.number().int().optional(),
|
|
72
|
+
premises: z.number().int().optional(),
|
|
73
|
+
intents: z.number().int().optional(),
|
|
74
|
+
opportunities: z.number().int().optional(),
|
|
75
|
+
negotiations: z.number().int().optional(),
|
|
76
|
+
/** Human-owner-only conversational (or unrecognized) question counts. */
|
|
77
|
+
chat: z.number().int().optional(),
|
|
78
|
+
}).strict();
|
|
79
|
+
/**
|
|
80
|
+
* Typed resolved MCP caller context consumed by the projection. Derived from
|
|
81
|
+
* the MCP capability subject at the transport boundary (see
|
|
82
|
+
* `resolveMcpActivityCaller` in mcp.authorization-policy.ts); absent on
|
|
83
|
+
* REST/chat surfaces, which are owner-trusted.
|
|
84
|
+
*/
|
|
85
|
+
export const McpActivityCallerSchema = z.object({
|
|
86
|
+
/** `'human'` callers own the summarized data and see every domain. */
|
|
87
|
+
kind: z.enum(["human", "agent"]),
|
|
88
|
+
/** Canonical `manage:*` permission actions granted to the caller. */
|
|
89
|
+
permissions: z.array(z.string()),
|
|
90
|
+
/** A network agent's bound community; always null for humans. */
|
|
91
|
+
networkScopeId: z.string().min(1).nullable(),
|
|
92
|
+
}).strict();
|
|
93
|
+
/** Summary domain → authorizing permission action for agent callers. */
|
|
94
|
+
const DOMAIN_PERMISSIONS = {
|
|
95
|
+
signals: "manage:intents",
|
|
96
|
+
opportunities: "manage:opportunities",
|
|
97
|
+
negotiations: "manage:negotiations",
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Affected question domain → authorizing permission action. `'chat'` is
|
|
101
|
+
* deliberately absent: conversational counts are human-owner-only and no
|
|
102
|
+
* agent permission releases them.
|
|
103
|
+
*/
|
|
104
|
+
const QUESTION_DOMAIN_PERMISSIONS = {
|
|
105
|
+
identity: "manage:identity",
|
|
106
|
+
premises: "manage:premises",
|
|
107
|
+
intents: "manage:intents",
|
|
108
|
+
opportunities: "manage:opportunities",
|
|
109
|
+
negotiations: "manage:negotiations",
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Canonical affected-domain permission an agent must hold to read or answer a
|
|
113
|
+
* question of the given mode. Returns `null` for human-owner-only questions
|
|
114
|
+
* (`chat`, and any unrecognized mode, which fail closed to the human-only
|
|
115
|
+
* bucket) — no agent permission can release those.
|
|
116
|
+
*
|
|
117
|
+
* This is the single shared mode → affected-domain → permission mapping, reusing
|
|
118
|
+
* `QUESTION_MODE_TO_DOMAIN` and `QUESTION_DOMAIN_PERMISSIONS` so question
|
|
119
|
+
* read/answer inheritance is identical to the `read_activity_summary`
|
|
120
|
+
* projection. It keys on `mode` only: the canonical question model does not vary
|
|
121
|
+
* a question's owning domain by `purpose` (purpose refines generation and
|
|
122
|
+
* provenance, not the affected domain), so purpose is intentionally not a
|
|
123
|
+
* discriminant here rather than being guessed at.
|
|
124
|
+
*/
|
|
125
|
+
export function questionModeRequiredPermission(mode) {
|
|
126
|
+
const domain = QUESTION_MODE_TO_DOMAIN[mode] ?? "chat";
|
|
127
|
+
return QUESTION_DOMAIN_PERMISSIONS[domain] ?? null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Whether an MCP caller may read or answer a question of the given mode. Human
|
|
131
|
+
* (owner) callers see every mode; agents are confined to modes backed by one of
|
|
132
|
+
* their exact affected-domain permissions. A network agent's binding is applied
|
|
133
|
+
* separately by the caller (network/intent clamp); this is purely the
|
|
134
|
+
* affected-domain permission gate.
|
|
135
|
+
*/
|
|
136
|
+
export function callerMayAccessQuestionMode(caller, mode) {
|
|
137
|
+
if (caller.kind === "human")
|
|
138
|
+
return true;
|
|
139
|
+
const required = questionModeRequiredPermission(mode);
|
|
140
|
+
return required !== null && caller.permissions.includes(required);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Explicit response contract for `read_activity_summary`. Every domain field
|
|
144
|
+
* is optional because agent callers receive only their authorized domains.
|
|
145
|
+
* Strict: no counterparty or unspecified field can pass validation.
|
|
146
|
+
*/
|
|
147
|
+
export const ActivitySummaryResponseSchema = z.object({
|
|
148
|
+
/** The reporting window actually used, in hours. */
|
|
149
|
+
sinceHours: z.number().int(),
|
|
150
|
+
/** signals domain — liveSignalsWatched and per-signal opportunity counts. */
|
|
151
|
+
liveSignalsWatched: z.number().int().optional(),
|
|
152
|
+
/** opportunities domain. */
|
|
153
|
+
opportunitiesSurfaced: z.number().int().optional(),
|
|
154
|
+
/** signals domain — signal IDs/titles, authorized by manage:intents only. */
|
|
155
|
+
opportunitiesBySignal: z.array(z.object({
|
|
156
|
+
intentId: z.string(),
|
|
157
|
+
title: z.string(),
|
|
158
|
+
count: z.number().int(),
|
|
159
|
+
}).strict()).optional(),
|
|
160
|
+
/** questions domain (meta-network) — counts grouped by affected domain. */
|
|
161
|
+
pendingQuestionsByDomain: ActivityQuestionCountsSchema.optional(),
|
|
162
|
+
answeredQuestionsByDomain: ActivityQuestionCountsSchema.optional(),
|
|
163
|
+
/** negotiations domain. */
|
|
164
|
+
negotiationsStarted: z.number().int().optional(),
|
|
165
|
+
negotiationsCompleted: z.number().int().optional(),
|
|
166
|
+
}).strict();
|
|
167
|
+
/**
|
|
168
|
+
* Resolves the summary domains a caller may see. Human owners receive every
|
|
169
|
+
* domain; agents receive only domains backed by one of their permissions.
|
|
170
|
+
* The `questions` domain only flags that at least one affected-domain count
|
|
171
|
+
* may be visible — each count is still filtered per affected domain in
|
|
172
|
+
* `projectActivitySummary`.
|
|
173
|
+
*/
|
|
174
|
+
export function resolveActivitySummaryDomains(caller) {
|
|
175
|
+
if (caller.kind === "human") {
|
|
176
|
+
return ["signals", "opportunities", "questions", "negotiations"];
|
|
177
|
+
}
|
|
178
|
+
const granted = new Set(caller.permissions);
|
|
179
|
+
const domains = [];
|
|
180
|
+
if (granted.has(DOMAIN_PERMISSIONS.signals))
|
|
181
|
+
domains.push("signals");
|
|
182
|
+
if (granted.has(DOMAIN_PERMISSIONS.opportunities))
|
|
183
|
+
domains.push("opportunities");
|
|
184
|
+
if (Object.values(QUESTION_DOMAIN_PERMISSIONS).some((action) => granted.has(action))) {
|
|
185
|
+
domains.push("questions");
|
|
186
|
+
}
|
|
187
|
+
if (granted.has(DOMAIN_PERMISSIONS.negotiations))
|
|
188
|
+
domains.push("negotiations");
|
|
189
|
+
return domains;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Returns the bound community a network agent's network-bound aggregates must
|
|
193
|
+
* be narrowed to in the query/adapter layer. Undefined for human callers and
|
|
194
|
+
* global agents, whose aggregates span the owner's networks.
|
|
195
|
+
*/
|
|
196
|
+
export function activitySummaryNetworkId(caller) {
|
|
197
|
+
if (caller.kind !== "agent")
|
|
198
|
+
return undefined;
|
|
199
|
+
return caller.networkScopeId ?? undefined;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Aggregates raw per-mode question counts into per-affected-domain counts,
|
|
203
|
+
* releasing only the domains the caller is authorized for. Meta-network:
|
|
204
|
+
* domain permissions are the only boundary — never a network filter.
|
|
205
|
+
*/
|
|
206
|
+
function projectQuestionCounts(caller, byMode) {
|
|
207
|
+
const granted = new Set(caller.permissions);
|
|
208
|
+
const counts = {};
|
|
209
|
+
for (const [mode, count] of Object.entries(byMode)) {
|
|
210
|
+
// Unrecognized modes fail closed to the human-only bucket.
|
|
211
|
+
const domain = QUESTION_MODE_TO_DOMAIN[mode] ?? "chat";
|
|
212
|
+
if (caller.kind === "agent") {
|
|
213
|
+
const permission = QUESTION_DOMAIN_PERMISSIONS[domain];
|
|
214
|
+
if (!permission || !granted.has(permission))
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
counts[domain] = (counts[domain] ?? 0) + count;
|
|
218
|
+
}
|
|
219
|
+
return Object.keys(counts).length > 0 ? counts : undefined;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Projects a full owner-scoped summary down to the caller's authorized
|
|
223
|
+
* domains. Pure field selection — no data is transformed or fabricated.
|
|
224
|
+
*/
|
|
225
|
+
export function projectActivitySummary(caller, summary) {
|
|
226
|
+
const domains = new Set(resolveActivitySummaryDomains(caller));
|
|
227
|
+
const projected = { sinceHours: summary.sinceHours };
|
|
228
|
+
if (domains.has("signals")) {
|
|
229
|
+
projected.liveSignalsWatched = summary.liveSignalsWatched;
|
|
230
|
+
projected.opportunitiesBySignal = summary.opportunitiesBySignal;
|
|
231
|
+
}
|
|
232
|
+
if (domains.has("opportunities")) {
|
|
233
|
+
projected.opportunitiesSurfaced = summary.opportunitiesSurfaced;
|
|
234
|
+
}
|
|
235
|
+
if (domains.has("questions")) {
|
|
236
|
+
const pending = projectQuestionCounts(caller, summary.pendingQuestionsByMode);
|
|
237
|
+
if (pending)
|
|
238
|
+
projected.pendingQuestionsByDomain = pending;
|
|
239
|
+
const answered = projectQuestionCounts(caller, summary.answeredQuestionsByMode);
|
|
240
|
+
if (answered)
|
|
241
|
+
projected.answeredQuestionsByDomain = answered;
|
|
242
|
+
}
|
|
243
|
+
if (domains.has("negotiations")) {
|
|
244
|
+
projected.negotiationsStarted = summary.negotiationsStarted;
|
|
245
|
+
projected.negotiationsCompleted = summary.negotiationsCompleted;
|
|
246
|
+
}
|
|
247
|
+
return projected;
|
|
248
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical guidance for Index Network protocol operations.
|
|
3
|
+
*
|
|
4
|
+
* This is the single normative source for:
|
|
5
|
+
* - Entity model and identity/context definitions
|
|
6
|
+
* - Premise, signal, community, network, and opportunity concepts
|
|
7
|
+
* - Negotiation semantics (owner approval vs A2A acceptance)
|
|
8
|
+
* - H2A and A2A collaboration (H2H is never exposed)
|
|
9
|
+
* - Retired vocabulary (no contact/Gmail/scrape/profile/ghost-user guidance)
|
|
10
|
+
*
|
|
11
|
+
* Wired into:
|
|
12
|
+
* - MCP_INSTRUCTIONS (packages/protocol/src/mcp/mcp.server.ts)
|
|
13
|
+
* - read_docs tool (packages/protocol/src/shared/agent/utility.tools.ts)
|
|
14
|
+
*
|
|
15
|
+
* IND-602, IND-603
|
|
16
|
+
*/
|
|
17
|
+
export declare const CANONICAL_GUIDANCE_TOPICS: readonly ["identity-context", "premises", "signals", "communities-networks", "opportunities", "negotiations", "workflows"];
|
|
18
|
+
export type CanonicalGuidanceTopic = (typeof CANONICAL_GUIDANCE_TOPICS)[number];
|
|
19
|
+
/**
|
|
20
|
+
* Summary of canonical entity model and protocol semantics.
|
|
21
|
+
* Used in MCP_INSTRUCTIONS and as read_docs summary across all surfaces.
|
|
22
|
+
* Never mentions retired contact/Gmail/scrape/profile/ghost-user guidance.
|
|
23
|
+
* Optimized to ~1900 chars to leave room for MCP_INSTRUCTIONS context budget.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CANONICAL_GUIDANCE_SUMMARY = "# Index Network Protocol\n\nIndex Network is a private, intent-driven discovery protocol. Users express signals (intents), agents find matches within shared networks, and decisions proceed through clear gates.\n\n## Core Concepts\n\n**Identity & Context** \u2014 User profile (name, bio, skills, interests, location) and current scope (networks, intents, stage).\n\n**Premises** \u2014 Foundational facts: background, experience, stage, timeline, constraints.\n\n**Signals** \u2014 What users seek (intents, opportunities). Drive semantic matching.\n\n**Communities & Networks** \u2014 Private groups where members share signals and discover connections via shared membership.\n\n**Opportunities** \u2014 Discovered matches between users. Lifecycle: draft \u2192 pending \u2192 accepted/rejected/expired.\n\n**Negotiations** \u2014 Agents coordinate, users approve. **A2A acceptance is not owner approval.** These are separate gates.\n\n**Workflows** \u2014 H2A (users express signals \u2192 agents discover) and A2A (agents coordinate) over MCP. Further escalation via native surfaces (human-to-human threads do not cross MCP).\n\n## Canonical Topics\n\nRefer to these for detailed entity facts and lifecycle:\n\n- **identity-context** \u2014 Profile structure, context scoping\n- **premises** \u2014 Background, stage, constraints\n- **signals** \u2014 Intent inference, classification\n- **communities-networks** \u2014 Membership, auto-assign\n- **opportunities** \u2014 Discovery, roles, reasoning\n- **negotiations** \u2014 Owner approval vs A2A, acceptance gates\n- **workflows** \u2014 H2A and A2A tool sequences";
|
|
26
|
+
/**
|
|
27
|
+
* Detailed canonical topic content for read_docs.
|
|
28
|
+
* Indexed by topic name; each contains current entity, capability, and lifecycle facts.
|
|
29
|
+
*/
|
|
30
|
+
export declare const CANONICAL_GUIDANCE_TOPICS_CONTENT: Record<CanonicalGuidanceTopic, string>;
|