@indexnetwork/protocol 14.3.2-rc.477.1 → 17.0.0-rc.479.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.
Files changed (184) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/IMPLEMENTATION.md +50 -52
  3. package/STABILITY.md +3 -3
  4. package/dist/chat/chat.agent.js +2 -3
  5. package/dist/chat/chat.graph.d.ts +41 -1
  6. package/dist/chat/chat.graph.js +108 -127
  7. package/dist/chat/negotiator.persona.d.ts +1 -1
  8. package/dist/chat/negotiator.persona.js +1 -4
  9. package/dist/chat/negotiator.prompt.js +1 -2
  10. package/dist/chat/onboarding.persona.js +0 -1
  11. package/dist/chat/reporter.persona.js +0 -1
  12. package/dist/chat/signal.persona.js +0 -1
  13. package/dist/contacts/application/contact.tools.d.ts +6 -9
  14. package/dist/contacts/application/contact.tools.js +11 -92
  15. package/dist/contacts/application/index.d.ts +2 -14
  16. package/dist/contacts/application/index.js +2 -13
  17. package/dist/contacts/domain/contact.types.d.ts +0 -23
  18. package/dist/contacts/domain/index.d.ts +2 -6
  19. package/dist/contacts/index.d.ts +1 -1
  20. package/dist/contacts/index.js +1 -1
  21. package/dist/contacts/ports/contact.repository.port.d.ts +5 -12
  22. package/dist/contacts/ports/contact.repository.port.js +4 -6
  23. package/dist/contacts/ports/contact.tools.port.d.ts +1 -3
  24. package/dist/contacts/ports/contact.tools.port.js +1 -2
  25. package/dist/contacts/ports/index.d.ts +1 -1
  26. package/dist/contacts/ports/index.js +1 -1
  27. package/dist/discovery/hyde.frame.d.ts +4 -4
  28. package/dist/discovery/hyde.graph.d.ts +71 -12
  29. package/dist/discovery/hyde.graph.js +337 -335
  30. package/dist/discovery/lens.inferrer.d.ts +6 -6
  31. package/dist/enrichment/enrichment.graph.d.ts +127 -9
  32. package/dist/enrichment/enrichment.graph.js +633 -655
  33. package/dist/enrichment/enrichment.state.d.ts +1 -1
  34. package/dist/enrichment/enrichment.tools.context-read.d.ts +10 -0
  35. package/dist/enrichment/enrichment.tools.context-read.js +353 -0
  36. package/dist/enrichment/enrichment.tools.context-write.d.ts +9 -0
  37. package/dist/enrichment/enrichment.tools.context-write.js +417 -0
  38. package/dist/enrichment/enrichment.tools.d.ts +11 -1
  39. package/dist/enrichment/enrichment.tools.helpers.d.ts +139 -0
  40. package/dist/enrichment/enrichment.tools.helpers.js +234 -0
  41. package/dist/enrichment/enrichment.tools.js +16 -975
  42. package/dist/index.d.ts +27 -50
  43. package/dist/index.js +17 -28
  44. package/dist/intents/application/intent.graph.d.ts +71 -67
  45. package/dist/intents/application/intent.graph.execute.d.ts +59 -0
  46. package/dist/intents/application/intent.graph.execute.js +301 -0
  47. package/dist/intents/application/intent.graph.infer.d.ts +44 -0
  48. package/dist/intents/application/intent.graph.infer.js +97 -0
  49. package/dist/intents/application/intent.graph.js +96 -888
  50. package/dist/intents/application/intent.graph.reconcile.d.ts +71 -0
  51. package/dist/intents/application/intent.graph.reconcile.js +274 -0
  52. package/dist/intents/application/intent.graph.shared.d.ts +70 -0
  53. package/dist/intents/application/intent.graph.shared.js +153 -0
  54. package/dist/intents/domain/intent.state.d.ts +1 -1
  55. package/dist/maintenance/maintenance.graph.d.ts +66 -3
  56. package/dist/maintenance/maintenance.graph.js +155 -156
  57. package/dist/mcp/mcp.authorization-policy.d.ts +24 -28
  58. package/dist/mcp/mcp.authorization-policy.js +14 -34
  59. package/dist/mcp/mcp.server.d.ts +3 -3
  60. package/dist/mcp/mcp.server.js +14 -20
  61. package/dist/negotiations/application/negotiation.candidates.d.ts +83 -0
  62. package/dist/negotiations/application/negotiation.candidates.js +162 -0
  63. package/dist/negotiations/application/negotiation.graph.d.ts +91 -157
  64. package/dist/negotiations/application/negotiation.graph.finalize.d.ts +5 -0
  65. package/dist/negotiations/application/negotiation.graph.finalize.js +280 -0
  66. package/dist/negotiations/application/negotiation.graph.init.d.ts +54 -0
  67. package/dist/negotiations/application/negotiation.graph.init.js +227 -0
  68. package/dist/negotiations/application/negotiation.graph.js +69 -1388
  69. package/dist/negotiations/application/negotiation.graph.screen.d.ts +23 -0
  70. package/dist/negotiations/application/negotiation.graph.screen.js +108 -0
  71. package/dist/negotiations/application/negotiation.graph.shared.d.ts +75 -0
  72. package/dist/negotiations/application/negotiation.graph.shared.js +125 -0
  73. package/dist/negotiations/application/negotiation.graph.turn.d.ts +105 -0
  74. package/dist/negotiations/application/negotiation.graph.turn.js +484 -0
  75. package/dist/negotiations/domain/negotiation.state.d.ts +1 -1
  76. package/dist/negotiations/domain/negotiation.state.js +0 -1
  77. package/dist/networks/application/indexer.graph.d.ts +165 -7
  78. package/dist/networks/application/indexer.graph.js +339 -388
  79. package/dist/networks/application/indexer.state.d.ts +1 -1
  80. package/dist/networks/application/membership.graph.d.ts +83 -5
  81. package/dist/networks/application/membership.graph.js +177 -207
  82. package/dist/networks/application/network.graph.d.ts +148 -5
  83. package/dist/networks/application/network.graph.js +249 -278
  84. package/dist/networks/domain/membership.state.d.ts +1 -1
  85. package/dist/networks/domain/network.state.d.ts +1 -1
  86. package/dist/opportunities/application/delivery-card.cache.d.ts +1 -1
  87. package/dist/opportunities/application/delivery-card.cache.js +2 -2
  88. package/dist/opportunities/application/index.d.ts +2 -2
  89. package/dist/opportunities/application/index.js +2 -2
  90. package/dist/opportunities/application/opportunity.evaluator.js +1 -1
  91. package/dist/opportunities/application/opportunity.graph.d.ts +686 -473
  92. package/dist/opportunities/application/opportunity.graph.discovery-strategies.d.ts +109 -0
  93. package/dist/opportunities/application/opportunity.graph.discovery-strategies.js +451 -0
  94. package/dist/opportunities/application/opportunity.graph.discovery.d.ts +69 -0
  95. package/dist/opportunities/application/opportunity.graph.discovery.js +397 -0
  96. package/dist/opportunities/application/opportunity.graph.evaluation.d.ts +82 -0
  97. package/dist/opportunities/application/opportunity.graph.evaluation.js +608 -0
  98. package/dist/opportunities/application/opportunity.graph.js +120 -3690
  99. package/dist/opportunities/application/opportunity.graph.modes.d.ts +538 -0
  100. package/dist/opportunities/application/opportunity.graph.modes.js +538 -0
  101. package/dist/opportunities/application/opportunity.graph.negotiate.d.ts +109 -0
  102. package/dist/opportunities/application/opportunity.graph.negotiate.js +392 -0
  103. package/dist/opportunities/application/opportunity.graph.persist-node.d.ts +93 -0
  104. package/dist/opportunities/application/opportunity.graph.persist-node.js +765 -0
  105. package/dist/opportunities/application/opportunity.graph.prep.d.ts +150 -0
  106. package/dist/opportunities/application/opportunity.graph.prep.js +381 -0
  107. package/dist/opportunities/application/opportunity.graph.shared.d.ts +173 -0
  108. package/dist/opportunities/application/opportunity.graph.shared.js +199 -0
  109. package/dist/opportunities/application/opportunity.presentation.d.ts +399 -0
  110. package/dist/opportunities/application/{opportunity.presenter.js → opportunity.presentation.js} +735 -9
  111. package/dist/opportunities/application/opportunity.tools.cards.d.ts +152 -0
  112. package/dist/opportunities/application/opportunity.tools.cards.js +235 -0
  113. package/dist/opportunities/application/opportunity.tools.d.ts +8 -114
  114. package/dist/opportunities/application/opportunity.tools.js +28 -711
  115. package/dist/opportunities/application/opportunity.tools.list.d.ts +10 -0
  116. package/dist/opportunities/application/opportunity.tools.list.js +493 -0
  117. package/dist/opportunities/domain/index.d.ts +3 -3
  118. package/dist/opportunities/domain/index.js +3 -3
  119. package/dist/opportunities/domain/opportunity.state.d.ts +19 -19
  120. package/dist/opportunities/index.d.ts +6 -6
  121. package/dist/opportunities/index.js +4 -4
  122. package/dist/opportunities/ports/opportunity.tools.port.d.ts +1 -1
  123. package/dist/opportunities/radar/radar.graph.d.ts +57 -13
  124. package/dist/opportunities/radar/radar.graph.js +470 -471
  125. package/dist/premises/premise.graph.d.ts +88 -20
  126. package/dist/premises/premise.graph.js +207 -218
  127. package/dist/questions/domain/question.schema.d.ts +40 -40
  128. package/dist/shared/agent/tool.factory.js +0 -8
  129. package/dist/shared/agent/tool.helpers.d.ts +21 -45
  130. package/dist/shared/agent/tool.helpers.js +1 -2
  131. package/dist/shared/agent/tool.registry.d.ts +4 -3
  132. package/dist/shared/agent/tool.registry.js +2 -4
  133. package/dist/shared/agent/tool.runtime.js +0 -2
  134. package/dist/shared/agent/utility.tools.js +9 -13
  135. package/dist/shared/interfaces/database.capabilities.d.ts +100 -0
  136. package/dist/shared/interfaces/database.capabilities.js +7 -0
  137. package/dist/shared/interfaces/database.entities.d.ts +533 -0
  138. package/dist/shared/interfaces/database.entities.js +10 -0
  139. package/dist/shared/interfaces/database.identity-queries.d.ts +294 -0
  140. package/dist/shared/interfaces/database.identity-queries.js +4 -0
  141. package/dist/shared/interfaces/database.interface.d.ts +15 -2277
  142. package/dist/shared/interfaces/database.interface.js +8 -0
  143. package/dist/shared/interfaces/database.member-queries.d.ts +221 -0
  144. package/dist/shared/interfaces/database.member-queries.js +4 -0
  145. package/dist/shared/interfaces/database.negotiation.d.ts +305 -0
  146. package/dist/shared/interfaces/database.negotiation.js +26 -0
  147. package/dist/shared/interfaces/database.network-queries.d.ts +277 -0
  148. package/dist/shared/interfaces/database.network-queries.js +4 -0
  149. package/dist/shared/interfaces/database.opportunity-queries.d.ts +285 -0
  150. package/dist/shared/interfaces/database.opportunity-queries.js +4 -0
  151. package/dist/shared/interfaces/database.port.d.ts +322 -0
  152. package/dist/shared/interfaces/database.port.js +29 -0
  153. package/dist/shared/schemas/discovery-question.schema.d.ts +14 -14
  154. package/dist/shared/schemas/negotiation-digest.schema.d.ts +2 -2
  155. package/package.json +2 -15
  156. package/dist/contacts/application/contact.inviter.d.ts +0 -49
  157. package/dist/contacts/application/contact.inviter.js +0 -64
  158. package/dist/integrations/application/index.d.ts +0 -14
  159. package/dist/integrations/application/index.js +0 -14
  160. package/dist/integrations/application/integration.tools.d.ts +0 -27
  161. package/dist/integrations/application/integration.tools.js +0 -98
  162. package/dist/integrations/domain/index.d.ts +0 -16
  163. package/dist/integrations/domain/index.js +0 -1
  164. package/dist/integrations/domain/integration.types.d.ts +0 -51
  165. package/dist/integrations/domain/integration.types.js +0 -9
  166. package/dist/integrations/index.d.ts +0 -10
  167. package/dist/integrations/index.js +0 -8
  168. package/dist/integrations/ports/index.d.ts +0 -25
  169. package/dist/integrations/ports/index.js +0 -23
  170. package/dist/integrations/ports/integration.adapter.port.d.ts +0 -62
  171. package/dist/integrations/ports/integration.adapter.port.js +0 -15
  172. package/dist/integrations/ports/integration.importer.port.d.ts +0 -31
  173. package/dist/integrations/ports/integration.importer.port.js +0 -15
  174. package/dist/integrations/ports/integration.tools.port.d.ts +0 -25
  175. package/dist/integrations/ports/integration.tools.port.js +0 -18
  176. package/dist/opportunities/application/opportunity.card-presentation.d.ts +0 -44
  177. package/dist/opportunities/application/opportunity.card-presentation.js +0 -93
  178. package/dist/opportunities/application/opportunity.presenter.d.ts +0 -156
  179. package/dist/opportunities/domain/opportunity.presentation-cache.d.ts +0 -5
  180. package/dist/opportunities/domain/opportunity.presentation-cache.js +0 -11
  181. package/dist/opportunities/domain/opportunity.presentation.d.ts +0 -76
  182. package/dist/opportunities/domain/opportunity.presentation.js +0 -516
  183. package/dist/opportunities/domain/opportunity.safe-presentation.d.ts +0 -104
  184. package/dist/opportunities/domain/opportunity.safe-presentation.js +0 -102
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Database operations for intent-network assignment and index ownership.
3
+ */
4
+ import type { UserIdentity } from '../schemas/identity.schema.js';
5
+ import type { NetworkAssignmentMetadata } from '../schemas/network-assignment.schema.js';
6
+ import type { ActiveIntent, AssignmentNetworkMembership, Id, IndexMemberDetails, IndexedIntentDetails, IntentNetworkFinalAssignmentResult, NetworkAssignmentContext, OwnedIndex, UpdateIndexSettingsData } from './database.entities.js';
7
+ /** Network assignment and owner-only index operations. */
8
+ export interface DatabaseNetworkQueries {
9
+ /**
10
+ * Intent fields needed for index appropriateness evaluation.
11
+ */
12
+ getIntentForIndexing(intentId: string): Promise<{
13
+ id: string;
14
+ payload: string;
15
+ userId: string;
16
+ sourceType: string | null;
17
+ sourceId: string | null;
18
+ } | null>;
19
+ /**
20
+ * Index + member prompts for a user in an index (only when member has autoAssign).
21
+ * Returns null if user is not a member or autoAssign is false.
22
+ */
23
+ getNetworkMemberContext(networkId: string, userId: string): Promise<NetworkAssignmentContext | null>;
24
+ /**
25
+ * Network memberships that should be considered for assignment policy. Unlike
26
+ * getUserIndexIds, this is not gated by network_members.autoAssign and carries
27
+ * personal-index metadata so scoped writes can include the user's personal network.
28
+ */
29
+ getAssignmentNetworkMembershipsForUser(userId: string): Promise<AssignmentNetworkMembership[]>;
30
+ /**
31
+ * Network IDs that should be considered for assignment policy. Unlike
32
+ * getUserIndexIds, this is not gated by network_members.autoAssign.
33
+ * @deprecated Prefer getAssignmentNetworkMembershipsForUser for scope-aware assignment.
34
+ */
35
+ getAssignmentNetworkIdsForUser(userId: string): Promise<string[]>;
36
+ /**
37
+ * Prompt context for assignment policy. Unlike getNetworkMemberContext, this is
38
+ * not gated by network_members.autoAssign.
39
+ */
40
+ getNetworkAssignmentContext(networkId: string, userId: string): Promise<NetworkAssignmentContext | null>;
41
+ /**
42
+ * Whether the intent is currently assigned to the index.
43
+ */
44
+ isIntentAssignedToIndex(intentId: string, networkId: string): Promise<boolean>;
45
+ /**
46
+ * Assigns an intent to an index (inserts intent_indexes row).
47
+ */
48
+ assignIntentToNetwork(intentId: string, networkId: string, relevancyScore?: number, assignmentMetadata?: NetworkAssignmentMetadata): Promise<void>;
49
+ /**
50
+ * Atomically assign an owned, non-archived intent only while the exact
51
+ * accepted network membership and network remain active. Implementations
52
+ * hold intent, network, and membership row locks through the insert.
53
+ */
54
+ assignIntentToNetworkIfMember(userId: string, intentId: string, networkId: string, relevancyScore?: number, assignmentMetadata?: NetworkAssignmentMetadata): Promise<IntentNetworkFinalAssignmentResult>;
55
+ /**
56
+ * Returns per-index relevancy scores for an intent's index assignments.
57
+ */
58
+ getIntentIndexScores(intentId: string): Promise<Array<{
59
+ networkId: string;
60
+ relevancyScore: number | null;
61
+ assignmentMetadata?: NetworkAssignmentMetadata | null;
62
+ }>>;
63
+ /**
64
+ * Removes an intent from an index (deletes intent_indexes row).
65
+ */
66
+ unassignIntentFromIndex(intentId: string, networkId: string): Promise<void>;
67
+ /**
68
+ * Returns all network IDs that an intent is registered to.
69
+ */
70
+ getNetworkIdsForIntent(intentId: string): Promise<string[]>;
71
+ /**
72
+ * Get indexes where the user has owner permissions.
73
+ * Returns full index details with member and intent counts.
74
+ *
75
+ * @param userId - The user ID to check ownership for
76
+ * @returns Array of owned indexes with counts
77
+ */
78
+ getOwnedIndexes(userId: string): Promise<OwnedIndex[]>;
79
+ /**
80
+ * Get public networks (joinPolicy 'anyone') that the user has not joined.
81
+ * Used for discovering communities available to join.
82
+ *
83
+ * @param userId - The user ID to check memberships against
84
+ * @returns Object containing array of public networks with owner info
85
+ */
86
+ getPublicIndexesNotJoined(userId: string): Promise<{
87
+ networks: Array<{
88
+ id: string;
89
+ title: string;
90
+ prompt: string | null;
91
+ memberCount: number;
92
+ owner: {
93
+ id: string;
94
+ name: string;
95
+ avatar: string | null;
96
+ } | null;
97
+ }>;
98
+ }>;
99
+ /**
100
+ * Check if user is an owner of a specific index.
101
+ *
102
+ * @param networkId - The index to check
103
+ * @param userId - The user to verify ownership for
104
+ * @returns True if user is an owner
105
+ */
106
+ isIndexOwner(networkId: string, userId: string): Promise<boolean>;
107
+ /**
108
+ * Check if user is a member of a specific index.
109
+ *
110
+ * @param networkId - The index to check
111
+ * @param userId - The user to verify membership for
112
+ * @returns True if user is a member
113
+ */
114
+ isNetworkMember(networkId: string, userId: string): Promise<boolean>;
115
+ /**
116
+ * Get all members of an index with their details.
117
+ * **OWNER ONLY** - throws if user is not an owner.
118
+ *
119
+ * @param networkId - The index to get members for
120
+ * @param requestingUserId - The user requesting (must be owner)
121
+ * @returns Array of member details with intent counts
122
+ * @throws Error if requestingUserId is not an owner
123
+ */
124
+ getNetworkMembersForOwner(networkId: string, requestingUserId: string): Promise<IndexMemberDetails[]>;
125
+ /**
126
+ * Get all members of an index with their details.
127
+ * **MEMBER ONLY** - any member of the index can list members (not just owners).
128
+ * Returns same shape as getNetworkMembersForOwner; email may be omitted for privacy.
129
+ *
130
+ * @param networkId - The index to get members for
131
+ * @param requestingUserId - The user requesting (must be a member of the index)
132
+ * @returns Array of member details with intent counts
133
+ * @throws Error if requestingUserId is not a member of the index
134
+ */
135
+ getNetworkMembersForMember(networkId: string, requestingUserId: string): Promise<IndexMemberDetails[]>;
136
+ /**
137
+ * Get all members from every network the user is a member of (deduplicated).
138
+ * Used for mentionable-users: anyone who shares at least one index with the requesting user.
139
+ *
140
+ * @param userId - The signed-in user
141
+ * @returns Array of member summaries (id, name, avatar only; no email)
142
+ */
143
+ getMembersFromUserIndexes(userId: Id<'users'>): Promise<{
144
+ userId: Id<'users'>;
145
+ name: string;
146
+ avatar: string | null;
147
+ }[]>;
148
+ /**
149
+ * Get all indexed intents for an index.
150
+ * **OWNER ONLY** - throws if user is not an owner.
151
+ *
152
+ * @param networkId - The index to get intents for
153
+ * @param requestingUserId - The user requesting (must be owner)
154
+ * @param options - Pagination options
155
+ * @returns Array of intent details with owner info
156
+ * @throws Error if requestingUserId is not an owner
157
+ */
158
+ getNetworkIntentsForOwner(networkId: string, requestingUserId: string, options?: {
159
+ limit?: number;
160
+ offset?: number;
161
+ }): Promise<IndexedIntentDetails[]>;
162
+ /**
163
+ * Get all indexed intents for an index.
164
+ * **MEMBER ONLY** - any member of the index can list intents (not just owners).
165
+ *
166
+ * @param networkId - The index to get intents for
167
+ * @param requestingUserId - The user requesting (must be a member of the index)
168
+ * @param options - Pagination options
169
+ * @returns Array of intent details with owner info
170
+ * @throws Error if requestingUserId is not a member of the index
171
+ */
172
+ getNetworkIntentsForMember(networkId: string, requestingUserId: string, options?: {
173
+ limit?: number;
174
+ offset?: number;
175
+ }): Promise<IndexedIntentDetails[]>;
176
+ /**
177
+ * Get the caller's own active intents across a set of indexes.
178
+ * Returns intents owned by `userId` that are linked (via intent_networks)
179
+ * to at least one of `indexIds`. Used by network-scoped agents to honor
180
+ * indexScope without falling back to global getActiveIntents (which would
181
+ * include intents in indexes outside scope).
182
+ *
183
+ * @param userId - The intent owner (always the caller).
184
+ * @param indexIds - The set of network IDs to filter on. Empty → empty result.
185
+ * @returns Active intents owned by userId in any of indexIds, deduped by intent id.
186
+ */
187
+ getActiveIntentsAcrossIndexes(userId: string, indexIds: string[]): Promise<ActiveIntent[]>;
188
+ /**
189
+ * Update index settings.
190
+ * **OWNER ONLY** - throws if user is not an owner.
191
+ *
192
+ * @param networkId - The index to update
193
+ * @param requestingUserId - The user requesting (must be owner)
194
+ * @param data - The settings to update
195
+ * @returns The updated index
196
+ * @throws Error if requestingUserId is not an owner
197
+ */
198
+ updateIndexSettings(networkId: string, requestingUserId: string, data: UpdateIndexSettingsData): Promise<OwnedIndex>;
199
+ /**
200
+ * Soft-delete a network (set deletedAt).
201
+ * Caller must ensure network is not personal and has no other members.
202
+ *
203
+ * @param networkId - The network to soft-delete
204
+ */
205
+ softDeleteNetwork(networkId: string): Promise<void>;
206
+ /**
207
+ * Delete a user's profile (removes profile row).
208
+ * Used after confirmation in chat tools.
209
+ *
210
+ * @param userId - User whose profile to delete
211
+ */
212
+ deleteProfile(userId: string): Promise<void>;
213
+ /**
214
+ * Get a user's profile including its row id (for update_user_context validation).
215
+ *
216
+ * @param userId - The user whose profile to fetch
217
+ * @returns Profile with id, or null if not found
218
+ */
219
+ getProfileByUserId(userId: string): Promise<(UserIdentity & {
220
+ id: string;
221
+ }) | null>;
222
+ /**
223
+ * Create a new index and return its record.
224
+ *
225
+ * @param data - Title, optional prompt, optional imageUrl, optional joinPolicy
226
+ * @returns The created network with id, title, prompt, imageUrl, permissions
227
+ */
228
+ createNetwork(data: {
229
+ title: string;
230
+ prompt?: string | null;
231
+ imageUrl?: string | null;
232
+ joinPolicy?: 'anyone' | 'invite_only';
233
+ }): Promise<{
234
+ id: string;
235
+ title: string;
236
+ prompt: string | null;
237
+ imageUrl: string | null;
238
+ permissions: {
239
+ joinPolicy: 'anyone' | 'invite_only';
240
+ invitationLink: {
241
+ code: string;
242
+ } | null;
243
+ };
244
+ }>;
245
+ /**
246
+ * Count members in an index (for delete guard).
247
+ *
248
+ * @param networkId - The index to count
249
+ * @returns Number of members
250
+ */
251
+ getNetworkMemberCount(networkId: string): Promise<number>;
252
+ /**
253
+ * Add a user as a member of a network.
254
+ *
255
+ * @param networkId - The network to add to
256
+ * @param userId - The user to add
257
+ * @param role - owner | member
258
+ * @returns success and optionally alreadyMember if they were already in the network
259
+ */
260
+ addMemberToNetwork(networkId: string, userId: string, role: 'owner' | 'member'): Promise<{
261
+ success: boolean;
262
+ alreadyMember?: boolean;
263
+ }>;
264
+ /**
265
+ * Removes a user from an index.
266
+ * Only the network owner can remove members. Cannot remove the owner.
267
+ *
268
+ * @param networkId - The index to remove from
269
+ * @param userId - The user to remove
270
+ * @returns success, or wasOwner/notMember if removal failed
271
+ */
272
+ removeMemberFromIndex(networkId: string, userId: string): Promise<{
273
+ success: boolean;
274
+ wasOwner?: boolean;
275
+ notMember?: boolean;
276
+ }>;
277
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Database operations for intent-network assignment and index ownership.
3
+ */
4
+ export {};
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Database operations for HyDE documents and the opportunity lifecycle.
3
+ */
4
+ import type { OutcomeOutbox } from './database.capabilities.js';
5
+ import type { CreateHydeDocumentData, CreateOpportunityData, HydeDocument, HydeSourceType, IntentScopedOpportunityPersistenceResult, Opportunity, OpportunityActor, OpportunityNetworkEligibility, OpportunityQueryOptions, OpportunityStatus } from './database.entities.js';
6
+ /** HyDE document and opportunity persistence operations. */
7
+ export interface DatabaseOpportunityQueries {
8
+ /**
9
+ * Get a HyDE document by source and strategy/lens hash.
10
+ * Returns the first matching document when multiple target corpuses exist.
11
+ *
12
+ * @param sourceType - 'intent' | 'query'
13
+ * @param sourceId - Source entity ID (e.g. intent ID, user ID)
14
+ * @param strategy - Lens hash (SHA-256 of lens label) or legacy strategy name
15
+ * @returns The HyDE document or null if not found
16
+ */
17
+ getHydeDocument(sourceType: HydeSourceType, sourceId: string, strategy: string): Promise<HydeDocument | null>;
18
+ /**
19
+ * Get all HyDE documents for a source (all strategies).
20
+ *
21
+ * @param sourceType - 'intent' | 'query'
22
+ * @param sourceId - Source entity ID
23
+ * @returns Array of HyDE documents for that source
24
+ */
25
+ getHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<HydeDocument[]>;
26
+ /**
27
+ * Save a HyDE document (upsert by sourceType + sourceId + strategy/lensHash + targetCorpus).
28
+ *
29
+ * @param data - HyDE document data
30
+ * @returns The saved HyDE document
31
+ */
32
+ saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;
33
+ /**
34
+ * Delete all HyDE documents for a source (e.g. when intent archived).
35
+ *
36
+ * @param sourceType - 'intent' | 'query'
37
+ * @param sourceId - Source entity ID
38
+ * @returns Number of documents deleted
39
+ */
40
+ deleteHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<number>;
41
+ /**
42
+ * Delete expired HyDE documents (expires_at <= now). Used by maintenance jobs.
43
+ *
44
+ * @returns Number of documents deleted
45
+ */
46
+ deleteExpiredHydeDocuments(): Promise<number>;
47
+ /**
48
+ * Get stale HyDE documents for refresh (e.g. createdAt < threshold).
49
+ *
50
+ * @param threshold - Date threshold; documents created before this are considered stale
51
+ * @returns Array of stale HyDE documents
52
+ */
53
+ getStaleHydeDocuments(threshold: Date): Promise<HydeDocument[]>;
54
+ /**
55
+ * Create a new opportunity.
56
+ *
57
+ * @param data - Opportunity creation data
58
+ * @returns The created opportunity
59
+ */
60
+ createOpportunity(data: CreateOpportunityData): Promise<Opportunity>;
61
+ /**
62
+ * Atomically create only while every actor still has an active membership on
63
+ * the actor's network. Implementations lock the membership rows through the
64
+ * insert commit so concurrent removal cannot race opportunity creation.
65
+ */
66
+ createOpportunityIfNetworkEligible?(data: CreateOpportunityData, eligibility: OpportunityNetworkEligibility): Promise<Opportunity | null>;
67
+ /**
68
+ * Intent-scoped discovery persistence boundary. Implementations serialize on
69
+ * normalized participant pair + trigger intent, re-check same-trigger recent
70
+ * duplicates and pair-global active negotiations, then create/expire while
71
+ * the existing network eligibility locks remain held.
72
+ */
73
+ persistIntentScopedOpportunityIfNetworkEligible?(data: CreateOpportunityData, expireIds: string[], eligibility: OpportunityNetworkEligibility & {
74
+ triggerIntentId: string;
75
+ }, dedupWindowMs: number): Promise<IntentScopedOpportunityPersistenceResult | null>;
76
+ /**
77
+ * Atomically update status only while the supplied participant anchors remain
78
+ * active and, when supplied, the opportunity still has `expectedStatus`.
79
+ * Used for discovery dedup reactivation races.
80
+ *
81
+ * @param id - Opportunity ID
82
+ * @param status - Target lifecycle status
83
+ * @param actors - Participant anchors that must remain network-eligible
84
+ * @param eligibility - Authoritative owner/network/intent scope
85
+ * @param expectedStatus - Optional compare-and-set source status
86
+ * @returns The updated opportunity, or null after eligibility/status drift
87
+ */
88
+ updateOpportunityStatusIfNetworkEligible?(id: string, status: OpportunityStatus, actors: OpportunityActor[], eligibility: OpportunityNetworkEligibility, expectedStatus?: OpportunityStatus): Promise<Opportunity | null>;
89
+ /**
90
+ * Get a single opportunity by ID.
91
+ *
92
+ * @param id - Opportunity ID
93
+ * @returns The opportunity or null if not found
94
+ */
95
+ getOpportunity(id: string): Promise<Opportunity | null>;
96
+ /**
97
+ * Get multiple opportunities by ID in a single batched query.
98
+ *
99
+ * Returns rows in arbitrary order; callers should index by `id`.
100
+ * Missing IDs are silently dropped (no error).
101
+ *
102
+ * @param ids - Opportunity IDs (deduplicated by the caller is fine but not required)
103
+ * @returns Opportunities found
104
+ */
105
+ getOpportunitiesByIds(ids: string[]): Promise<Opportunity[]>;
106
+ /**
107
+ * Find opportunities that superseded a previous opportunity through enrichment.
108
+ * Uses the existing JSONB `detection.enrichedFrom` array, so no schema-level relation is required.
109
+ * Results are newest-first so callers can choose the newest visible replacement.
110
+ *
111
+ * @param opportunityId - Superseded opportunity ID
112
+ * @returns Replacement opportunities, newest first
113
+ */
114
+ findEnrichedReplacementOpportunities(opportunityId: string): Promise<Opportunity[]>;
115
+ /**
116
+ * Resolve an opportunity identifier (full UUID or short prefix) to a full UUID.
117
+ * @param idOrPrefix - Full UUID or short hex prefix
118
+ * @param userId - The user ID (for visibility scoping)
119
+ * @returns Resolved ID, ambiguous marker, or null if not found
120
+ */
121
+ resolveOpportunityId(idOrPrefix: string, userId: string): Promise<{
122
+ id: string;
123
+ } | {
124
+ ambiguous: true;
125
+ } | null>;
126
+ /**
127
+ * Get opportunities for a user (as any actor role).
128
+ *
129
+ * @param userId - User ID (actor userId)
130
+ * @param options - Optional filters and pagination
131
+ * @returns Array of opportunities
132
+ */
133
+ getOpportunitiesForUser(userId: string, options?: OpportunityQueryOptions): Promise<Opportunity[]>;
134
+ /**
135
+ * Get the live candidate pool created exactly by one intent and visible to
136
+ * its recipient. Unlike selected-intent reads, this never falls back to an
137
+ * actor.intent match.
138
+ */
139
+ getLivePoolOpportunitiesForIntent(recipientUserId: string, intentId: string): Promise<Opportunity[]>;
140
+ /**
141
+ * Get opportunities in an index (for index admins).
142
+ *
143
+ * @param networkId - Network ID
144
+ * @param options - Optional filters and pagination
145
+ * @returns Array of opportunities
146
+ */
147
+ getOpportunitiesForNetwork(networkId: string, options?: OpportunityQueryOptions): Promise<Opportunity[]>;
148
+ /**
149
+ * Update an opportunity's status.
150
+ *
151
+ * @param id - Opportunity ID
152
+ * @param status - New status
153
+ * @param acceptedBy - Required when `status === 'accepted'`
154
+ * @param outbox - Optional IND-434 atomic outcome-capture (same-txn insert)
155
+ * @returns The updated opportunity or null if not found
156
+ */
157
+ updateOpportunityStatus(id: string, status: OpportunityStatus, acceptedBy?: string, outbox?: OutcomeOutbox): Promise<Opportunity | null>;
158
+ /**
159
+ * Atomically restores a taskless negotiation attempt to its pre-negotiation status.
160
+ * Serializes with exact-attempt task creation, then transitions only the exact
161
+ * still-current `negotiating` version when no qualifying negotiation task exists.
162
+ *
163
+ * @param id - Opportunity ID
164
+ * @param expectedUpdatedAt - Persistence boundary for this negotiation attempt
165
+ * @param fallbackStatus - Status restored when the guarded transition succeeds
166
+ * @returns The compensated opportunity, or null on a status, version, or task race
167
+ */
168
+ compensateTasklessNegotiatingOpportunity(id: string, expectedUpdatedAt: Date, fallbackStatus: 'latent' | 'draft'): Promise<Opportunity | null>;
169
+ /**
170
+ * Stamp `actedAt` on the actor matching `actorUserId` and update the
171
+ * opportunity's status atomically (row-lock + JSONB merge in one txn).
172
+ *
173
+ * Used by `sendNode` (status → 'pending') and `updateNode` (status →
174
+ * 'accepted'). The self-accept guard is enforced in the caller, not here —
175
+ * this method blindly stamps. Callers must pre-check `actor.actedAt` before
176
+ * invocation when the semantics require it (i.e. accepting).
177
+ *
178
+ * @param id - Opportunity ID
179
+ * @param actorUserId - The user whose actor entry should be stamped
180
+ * @param status - New opportunity status
181
+ * @param acceptedBy - Required when `status === 'accepted'`
182
+ * @param outbox - Optional IND-434 atomic outcome-capture (same-txn insert)
183
+ * @returns The updated opportunity, or null if not found
184
+ */
185
+ stampOpportunityActorAction(id: string, actorUserId: string, status: OpportunityStatus, acceptedBy?: string, outbox?: OutcomeOutbox): Promise<Opportunity | null>;
186
+ /**
187
+ * Update the `approved` field on an opportunity's introducer actor.
188
+ * Fetches the opportunity, patches the matching actor in JS, and writes
189
+ * the updated actors JSONB back. Returns the updated opportunity or null.
190
+ */
191
+ updateOpportunityActorApproval(id: string, introducerUserId: string, approved: boolean): Promise<Opportunity | null>;
192
+ /**
193
+ * Create one opportunity and expire others in a single transaction.
194
+ * Atomic: insert then update status to 'expired' for each id in expireIds.
195
+ * Used when enriching replaces overlapping opportunities so subscribers see consistent state.
196
+ *
197
+ * @param data - Opportunity creation data (caller may set status when enriched)
198
+ * @param expireIds - Opportunity IDs to set status to 'expired'
199
+ * @returns The created opportunity and the list of opportunities that were expired
200
+ */
201
+ createOpportunityAndExpireIds(data: CreateOpportunityData, expireIds: string[]): Promise<{
202
+ created: Opportunity;
203
+ expired: Opportunity[];
204
+ }>;
205
+ /** Eligibility-locked variant of create+expire for discovery persistence. */
206
+ createOpportunityAndExpireIdsIfNetworkEligible?(data: CreateOpportunityData, expireIds: string[], eligibility: OpportunityNetworkEligibility): Promise<{
207
+ created: Opportunity;
208
+ expired: Opportunity[];
209
+ } | null>;
210
+ /**
211
+ * Check if an opportunity already exists between the given actors in the index (deduplication).
212
+ *
213
+ * @param actorIds - Array of user IDs that would be actors
214
+ * @param networkId - Network ID
215
+ * @returns True if a non-expired opportunity exists with exactly these actors in this network
216
+ */
217
+ opportunityExistsBetweenActors(actorIds: string[], networkId: string): Promise<boolean>;
218
+ /**
219
+ * Find opportunities whose actors contain all the given user IDs.
220
+ *
221
+ * The `includeIntroducers` flag controls actor matching: when false (default), matching
222
+ * is restricted to non-introducer roles; when true, any role in `actors` counts.
223
+ *
224
+ * Index-agnostic. Ordered by updatedAt desc.
225
+ *
226
+ * @param actorIds - User IDs that must all appear in each returned opportunity's actors
227
+ * @param options - includeIntroducers (default false), statuses (include filter), excludeStatuses (exclude filter)
228
+ * @returns Matching opportunities, newest first
229
+ */
230
+ findOpportunitiesByActors(actorIds: string[], options?: {
231
+ includeIntroducers?: boolean;
232
+ statuses?: OpportunityStatus[];
233
+ excludeStatuses?: OpportunityStatus[];
234
+ }): Promise<Opportunity[]>;
235
+ /**
236
+ * IND-567 Rejection cool-down: returns the subset of `candidateUserIds` that
237
+ * have at least one non-draft opportunity with `discovererId` whose `updatedAt`
238
+ * falls within the last `windowMs` milliseconds AND whose status is `rejected`
239
+ * or `stalled`. Used by the evaluation node to apply a score penalty before
240
+ * sending candidates to the LLM, suppressing cross-query re-surfacing of
241
+ * recently-rejected pairs.
242
+ *
243
+ * Optional — adapters that do not implement it return `undefined`; the graph
244
+ * degrades gracefully (no penalty applied, dedup persist-node guard still fires).
245
+ *
246
+ * @param discovererId - User running discovery
247
+ * @param candidateUserIds - Candidate user IDs to check (may be empty — return [])
248
+ * @param windowMs - Look-back window in milliseconds
249
+ * @returns Candidate user IDs (subset of input) with a recent rejected/stalled opp
250
+ */
251
+ getRecentlyRejectedOpportunityCounterparties?(discovererId: string, candidateUserIds: string[], windowMs: number): Promise<string[]>;
252
+ /**
253
+ * Expire opportunities referencing an intent (e.g. when intent is archived).
254
+ *
255
+ * @param intentId - Intent ID to match in opportunity actors
256
+ * @returns Number of opportunities updated to expired
257
+ */
258
+ expireOpportunitiesByIntent(intentId: string): Promise<number>;
259
+ /**
260
+ * Expire opportunities for a user removed from an index.
261
+ *
262
+ * @param networkId - Network ID
263
+ * @param userId - User ID that was removed
264
+ * @returns Number of opportunities updated to expired
265
+ */
266
+ expireOpportunitiesForRemovedMember(networkId: string, userId: string): Promise<number>;
267
+ /**
268
+ * Expire opportunities whose expires_at <= now. Used by maintenance cron.
269
+ *
270
+ * @returns Number of opportunities updated to expired
271
+ */
272
+ expireStaleOpportunities(): Promise<number>;
273
+ /**
274
+ * Accept all sibling opportunities between the same actor pair in one transaction.
275
+ * Selects opportunities where both userId and counterpartUserId are actors and status
276
+ * is not accepted/expired/rejected, excludes excludeOpportunityId, then bulk-updates status to accepted.
277
+ * Rolls back on any failure.
278
+ *
279
+ * @param userId - First actor user ID
280
+ * @param counterpartUserId - Second actor user ID
281
+ * @param excludeOpportunityId - Opportunity ID to exclude (the one already being accepted)
282
+ * @returns IDs of opportunities that were updated to accepted
283
+ */
284
+ acceptSiblingOpportunities(userId: string, counterpartUserId: string, excludeOpportunityId: string): Promise<string[]>;
285
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Database operations for HyDE documents and the opportunity lifecycle.
3
+ */
4
+ export {};