@indexnetwork/protocol 14.3.2-rc.477.1 → 16.1.1-rc.478.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 (140) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/IMPLEMENTATION.md +50 -52
  3. package/STABILITY.md +3 -3
  4. package/dist/chat/chat.agent.js +2 -2
  5. package/dist/chat/chat.graph.d.ts +41 -1
  6. package/dist/chat/chat.graph.js +108 -127
  7. package/dist/discovery/hyde.frame.d.ts +4 -4
  8. package/dist/discovery/hyde.graph.d.ts +71 -12
  9. package/dist/discovery/hyde.graph.js +337 -335
  10. package/dist/discovery/lens.inferrer.d.ts +6 -6
  11. package/dist/enrichment/enrichment.graph.d.ts +127 -9
  12. package/dist/enrichment/enrichment.graph.js +633 -655
  13. package/dist/enrichment/enrichment.state.d.ts +1 -1
  14. package/dist/enrichment/enrichment.tools.context-read.d.ts +10 -0
  15. package/dist/enrichment/enrichment.tools.context-read.js +353 -0
  16. package/dist/enrichment/enrichment.tools.context-write.d.ts +9 -0
  17. package/dist/enrichment/enrichment.tools.context-write.js +417 -0
  18. package/dist/enrichment/enrichment.tools.d.ts +11 -1
  19. package/dist/enrichment/enrichment.tools.helpers.d.ts +139 -0
  20. package/dist/enrichment/enrichment.tools.helpers.js +234 -0
  21. package/dist/enrichment/enrichment.tools.js +16 -975
  22. package/dist/index.d.ts +27 -48
  23. package/dist/index.js +17 -27
  24. package/dist/intents/application/intent.graph.d.ts +71 -67
  25. package/dist/intents/application/intent.graph.execute.d.ts +59 -0
  26. package/dist/intents/application/intent.graph.execute.js +301 -0
  27. package/dist/intents/application/intent.graph.infer.d.ts +44 -0
  28. package/dist/intents/application/intent.graph.infer.js +97 -0
  29. package/dist/intents/application/intent.graph.js +96 -888
  30. package/dist/intents/application/intent.graph.reconcile.d.ts +71 -0
  31. package/dist/intents/application/intent.graph.reconcile.js +274 -0
  32. package/dist/intents/application/intent.graph.shared.d.ts +70 -0
  33. package/dist/intents/application/intent.graph.shared.js +153 -0
  34. package/dist/intents/domain/intent.state.d.ts +1 -1
  35. package/dist/maintenance/maintenance.graph.d.ts +66 -3
  36. package/dist/maintenance/maintenance.graph.js +155 -156
  37. package/dist/mcp/mcp.authorization-policy.d.ts +24 -28
  38. package/dist/mcp/mcp.authorization-policy.js +14 -34
  39. package/dist/mcp/mcp.server.d.ts +3 -3
  40. package/dist/mcp/mcp.server.js +12 -16
  41. package/dist/negotiations/application/negotiation.candidates.d.ts +83 -0
  42. package/dist/negotiations/application/negotiation.candidates.js +162 -0
  43. package/dist/negotiations/application/negotiation.graph.d.ts +91 -157
  44. package/dist/negotiations/application/negotiation.graph.finalize.d.ts +5 -0
  45. package/dist/negotiations/application/negotiation.graph.finalize.js +280 -0
  46. package/dist/negotiations/application/negotiation.graph.init.d.ts +54 -0
  47. package/dist/negotiations/application/negotiation.graph.init.js +227 -0
  48. package/dist/negotiations/application/negotiation.graph.js +69 -1388
  49. package/dist/negotiations/application/negotiation.graph.screen.d.ts +23 -0
  50. package/dist/negotiations/application/negotiation.graph.screen.js +108 -0
  51. package/dist/negotiations/application/negotiation.graph.shared.d.ts +75 -0
  52. package/dist/negotiations/application/negotiation.graph.shared.js +125 -0
  53. package/dist/negotiations/application/negotiation.graph.turn.d.ts +105 -0
  54. package/dist/negotiations/application/negotiation.graph.turn.js +484 -0
  55. package/dist/negotiations/domain/negotiation.state.d.ts +1 -1
  56. package/dist/negotiations/domain/negotiation.state.js +0 -1
  57. package/dist/networks/application/indexer.graph.d.ts +165 -7
  58. package/dist/networks/application/indexer.graph.js +339 -388
  59. package/dist/networks/application/indexer.state.d.ts +1 -1
  60. package/dist/networks/application/membership.graph.d.ts +83 -5
  61. package/dist/networks/application/membership.graph.js +177 -207
  62. package/dist/networks/application/network.graph.d.ts +148 -5
  63. package/dist/networks/application/network.graph.js +249 -278
  64. package/dist/networks/domain/membership.state.d.ts +1 -1
  65. package/dist/networks/domain/network.state.d.ts +1 -1
  66. package/dist/opportunities/application/delivery-card.cache.d.ts +1 -1
  67. package/dist/opportunities/application/delivery-card.cache.js +2 -2
  68. package/dist/opportunities/application/index.d.ts +2 -2
  69. package/dist/opportunities/application/index.js +2 -2
  70. package/dist/opportunities/application/opportunity.evaluator.js +1 -1
  71. package/dist/opportunities/application/opportunity.graph.d.ts +686 -473
  72. package/dist/opportunities/application/opportunity.graph.discovery-strategies.d.ts +109 -0
  73. package/dist/opportunities/application/opportunity.graph.discovery-strategies.js +451 -0
  74. package/dist/opportunities/application/opportunity.graph.discovery.d.ts +69 -0
  75. package/dist/opportunities/application/opportunity.graph.discovery.js +397 -0
  76. package/dist/opportunities/application/opportunity.graph.evaluation.d.ts +82 -0
  77. package/dist/opportunities/application/opportunity.graph.evaluation.js +608 -0
  78. package/dist/opportunities/application/opportunity.graph.js +120 -3690
  79. package/dist/opportunities/application/opportunity.graph.modes.d.ts +538 -0
  80. package/dist/opportunities/application/opportunity.graph.modes.js +538 -0
  81. package/dist/opportunities/application/opportunity.graph.negotiate.d.ts +109 -0
  82. package/dist/opportunities/application/opportunity.graph.negotiate.js +392 -0
  83. package/dist/opportunities/application/opportunity.graph.persist-node.d.ts +93 -0
  84. package/dist/opportunities/application/opportunity.graph.persist-node.js +765 -0
  85. package/dist/opportunities/application/opportunity.graph.prep.d.ts +150 -0
  86. package/dist/opportunities/application/opportunity.graph.prep.js +381 -0
  87. package/dist/opportunities/application/opportunity.graph.shared.d.ts +173 -0
  88. package/dist/opportunities/application/opportunity.graph.shared.js +199 -0
  89. package/dist/opportunities/application/opportunity.presentation.d.ts +399 -0
  90. package/dist/opportunities/application/{opportunity.presenter.js → opportunity.presentation.js} +735 -9
  91. package/dist/opportunities/application/opportunity.tools.cards.d.ts +152 -0
  92. package/dist/opportunities/application/opportunity.tools.cards.js +235 -0
  93. package/dist/opportunities/application/opportunity.tools.d.ts +8 -114
  94. package/dist/opportunities/application/opportunity.tools.js +28 -711
  95. package/dist/opportunities/application/opportunity.tools.list.d.ts +10 -0
  96. package/dist/opportunities/application/opportunity.tools.list.js +493 -0
  97. package/dist/opportunities/domain/index.d.ts +3 -3
  98. package/dist/opportunities/domain/index.js +3 -3
  99. package/dist/opportunities/domain/opportunity.state.d.ts +19 -19
  100. package/dist/opportunities/index.d.ts +6 -6
  101. package/dist/opportunities/index.js +4 -4
  102. package/dist/opportunities/ports/opportunity.tools.port.d.ts +1 -1
  103. package/dist/opportunities/radar/radar.graph.d.ts +57 -13
  104. package/dist/opportunities/radar/radar.graph.js +470 -471
  105. package/dist/premises/premise.graph.d.ts +88 -20
  106. package/dist/premises/premise.graph.js +207 -218
  107. package/dist/questions/domain/question.schema.d.ts +40 -40
  108. package/dist/shared/agent/tool.helpers.d.ts +21 -0
  109. package/dist/shared/agent/tool.registry.d.ts +4 -3
  110. package/dist/shared/agent/tool.registry.js +1 -1
  111. package/dist/shared/interfaces/database.capabilities.d.ts +100 -0
  112. package/dist/shared/interfaces/database.capabilities.js +7 -0
  113. package/dist/shared/interfaces/database.entities.d.ts +533 -0
  114. package/dist/shared/interfaces/database.entities.js +10 -0
  115. package/dist/shared/interfaces/database.identity-queries.d.ts +294 -0
  116. package/dist/shared/interfaces/database.identity-queries.js +4 -0
  117. package/dist/shared/interfaces/database.interface.d.ts +15 -2277
  118. package/dist/shared/interfaces/database.interface.js +8 -0
  119. package/dist/shared/interfaces/database.member-queries.d.ts +228 -0
  120. package/dist/shared/interfaces/database.member-queries.js +4 -0
  121. package/dist/shared/interfaces/database.negotiation.d.ts +305 -0
  122. package/dist/shared/interfaces/database.negotiation.js +26 -0
  123. package/dist/shared/interfaces/database.network-queries.d.ts +277 -0
  124. package/dist/shared/interfaces/database.network-queries.js +4 -0
  125. package/dist/shared/interfaces/database.opportunity-queries.d.ts +285 -0
  126. package/dist/shared/interfaces/database.opportunity-queries.js +4 -0
  127. package/dist/shared/interfaces/database.port.d.ts +322 -0
  128. package/dist/shared/interfaces/database.port.js +29 -0
  129. package/dist/shared/schemas/discovery-question.schema.d.ts +14 -14
  130. package/dist/shared/schemas/negotiation-digest.schema.d.ts +2 -2
  131. package/package.json +2 -15
  132. package/dist/opportunities/application/opportunity.card-presentation.d.ts +0 -44
  133. package/dist/opportunities/application/opportunity.card-presentation.js +0 -93
  134. package/dist/opportunities/application/opportunity.presenter.d.ts +0 -156
  135. package/dist/opportunities/domain/opportunity.presentation-cache.d.ts +0 -5
  136. package/dist/opportunities/domain/opportunity.presentation-cache.js +0 -11
  137. package/dist/opportunities/domain/opportunity.presentation.d.ts +0 -76
  138. package/dist/opportunities/domain/opportunity.presentation.js +0 -516
  139. package/dist/opportunities/domain/opportunity.safe-presentation.d.ts +0 -104
  140. package/dist/opportunities/domain/opportunity.safe-presentation.js +0 -102
@@ -1 +1,9 @@
1
+ /**
2
+ * The database port, re-exported as one surface.
3
+ *
4
+ * The declarations moved into sibling modules — entities, the four query
5
+ * groups that compose `Database`, the access-scoped views, negotiation
6
+ * persistence, and the capability-narrowed aliases. Importers keep using this
7
+ * path; nothing about the types changed.
8
+ */
1
9
  export {};
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Database operations for contacts, premises, and user contexts.
3
+ */
4
+ import type { NetworkAssignmentMetadata } from '../schemas/network-assignment.schema.js';
5
+ import type { PremiseAnalysis, PremiseAssertion, PremiseProvenance, PremiseRecord, PremiseValidity } from './database.entities.js';
6
+ /** Contact, premise and user-context operations. */
7
+ export interface DatabaseMemberQueries {
8
+ /** Create a ghost user (unregistered contact) with empty profile. */
9
+ createGhostUser(data: {
10
+ name: string;
11
+ email: string;
12
+ }): Promise<{
13
+ id: string;
14
+ }>;
15
+ /** Upsert a contact membership in the owner's personal network (index_members with permissions=['contact']). */
16
+ upsertContactMembership(ownerId: string, contactUserId: string, options?: {
17
+ restore?: boolean;
18
+ }): Promise<void>;
19
+ /**
20
+ * Finds an existing DM conversation between two users, or creates one.
21
+ * Uses a unique `dmPair` column (sorted user IDs joined by ':') to
22
+ * prevent duplicate DMs under concurrency. Used by the Start Chat flow
23
+ * (Plan B Task 8) to atomically surface the h2h conversation when
24
+ * accepting an opportunity.
25
+ */
26
+ getOrCreateDM(userA: string, userB: string, participantType?: 'user' | 'agent'): Promise<{
27
+ id: string;
28
+ }>;
29
+ /**
30
+ * Clears hiddenAt for a user on a conversation, making it visible in their
31
+ * conversation list again. Called by startChat when reusing an existing DM
32
+ * that the user had previously hidden.
33
+ */
34
+ unhideConversation(userId: string, conversationId: string): Promise<void>;
35
+ /** Hard-delete a contact membership from the owner's personal network. */
36
+ hardDeleteContactMembership(ownerId: string, contactUserId: string): Promise<void>;
37
+ /** Get all contact members from the owner's personal network with user details. */
38
+ getContactMembers(ownerId: string): Promise<Array<{
39
+ userId: string;
40
+ user: {
41
+ id: string;
42
+ name: string;
43
+ email: string;
44
+ avatar: string | null;
45
+ isGhost: boolean;
46
+ };
47
+ }>>;
48
+ /** Clear a reverse opt-out (reactivate soft-deleted contact membership in another user's personal network). */
49
+ clearReverseOptOut(ownerId: string, otherUserId: string): Promise<void>;
50
+ /**
51
+ * Returns the IDs of personal networks where the given user is a contact member.
52
+ * Used for auto-assigning new intents to personal networks of contacts who imported this user.
53
+ *
54
+ * @param userId - The user whose contact memberships to look up
55
+ * @returns Array of personal network IDs
56
+ */
57
+ getPersonalIndexesForContact(userId: string): Promise<{
58
+ networkId: string;
59
+ }[]>;
60
+ /** Find a user by email. */
61
+ getUserByEmail(email: string): Promise<{
62
+ id: string;
63
+ name: string;
64
+ email: string;
65
+ isGhost: boolean;
66
+ } | null>;
67
+ createPremise(input: {
68
+ userId: string;
69
+ assertion: PremiseAssertion;
70
+ provenance: PremiseProvenance;
71
+ analysis?: PremiseAnalysis;
72
+ validity: PremiseValidity;
73
+ embedding?: number[];
74
+ }): Promise<PremiseRecord>;
75
+ getPremise(premiseId: string): Promise<PremiseRecord | null>;
76
+ getPremisesForUser(userId: string, status?: 'ACTIVE' | 'RETRACTED' | 'EXPIRED'): Promise<PremiseRecord[]>;
77
+ /**
78
+ * Retrieve a user's premises assigned to one of the provided networks.
79
+ * Optional for older/test adapters; OpportunityGraph falls back to capped
80
+ * getPremisesForUser results when unavailable.
81
+ */
82
+ getPremisesForUserInNetworks?(userId: string, networkIds: string[], status?: 'ACTIVE' | 'RETRACTED' | 'EXPIRED', limit?: number): Promise<PremiseRecord[]>;
83
+ updatePremise(premiseId: string, updates: {
84
+ assertion?: PremiseAssertion;
85
+ analysis?: PremiseAnalysis;
86
+ validity?: PremiseValidity;
87
+ embedding?: number[];
88
+ status?: 'ACTIVE' | 'RETRACTED' | 'EXPIRED';
89
+ retractedAt?: Date;
90
+ }): Promise<PremiseRecord>;
91
+ assignPremiseToNetwork(premiseId: string, networkId: string, relevancyScore: number, assignmentMetadata?: NetworkAssignmentMetadata): Promise<void>;
92
+ getPremiseNetworks(premiseId: string): Promise<Array<{
93
+ networkId: string;
94
+ relevancyScore: number | null;
95
+ assignmentMetadata?: NetworkAssignmentMetadata | null;
96
+ }>>;
97
+ /**
98
+ * Cosine similarity search against premise embeddings, scoped to shared networks.
99
+ * Used by the opportunity graph's premise discovery path (path D).
100
+ */
101
+ searchPremisesBySimilarity(params: {
102
+ embedding: number[];
103
+ networkIds: string[];
104
+ excludeUserId: string;
105
+ limit: number;
106
+ minScore?: number;
107
+ }): Promise<Array<{
108
+ premiseId: string;
109
+ userId: string;
110
+ networkId: string;
111
+ assertionText: string;
112
+ similarity: number;
113
+ }>>;
114
+ /**
115
+ * Cosine similarity search against user_context embeddings, scoped to shared networks.
116
+ * Matches only per-network context rows (the global networkId-null row is never a
117
+ * candidate), excluding the discovering user. Optional — lightweight-mode
118
+ * context-to-context discovery no-ops when the adapter omits it.
119
+ */
120
+ searchUserContextsBySimilarity?(params: {
121
+ embedding: number[];
122
+ networkIds: string[];
123
+ excludeUserId: string;
124
+ limit: number;
125
+ minScore?: number;
126
+ }): Promise<Array<{
127
+ contextId: string;
128
+ userId: string;
129
+ networkId: string;
130
+ text: string;
131
+ similarity: number;
132
+ }>>;
133
+ /**
134
+ * Batched version of premise similarity search. Executes one bounded DB call
135
+ * for all selected source premises instead of one query per source premise.
136
+ * Optional for older/test adapters; OpportunityGraph falls back to the
137
+ * single-source method when unavailable.
138
+ */
139
+ searchPremisesBySimilarityBatch?(params: {
140
+ sources: Array<{
141
+ premiseId: string;
142
+ embedding: number[];
143
+ }>;
144
+ networkIds: string[];
145
+ excludeUserId: string;
146
+ limitPerSource: number;
147
+ minScore?: number;
148
+ }): Promise<Array<{
149
+ sourcePremiseId: string;
150
+ premiseId: string;
151
+ userId: string;
152
+ networkId: string;
153
+ assertionText: string;
154
+ similarity: number;
155
+ }>>;
156
+ /**
157
+ * Find the single most-similar ACTIVE premise belonging to the SAME user whose
158
+ * cosine similarity to `embedding` meets or exceeds `threshold`. Used by the
159
+ * premise graph to skip near-duplicate premises on create. Returns null when no
160
+ * active premise clears the threshold (or the user has none with an embedding).
161
+ * Optional so older/test adapters can omit it — the premise graph skips dedup
162
+ * when it is unavailable.
163
+ */
164
+ findSimilarActivePremise?(params: {
165
+ userId: string;
166
+ embedding: number[];
167
+ threshold: number;
168
+ }): Promise<{
169
+ premiseId: string;
170
+ assertionText: string;
171
+ similarity: number;
172
+ } | null>;
173
+ /**
174
+ * Upsert a user context. Pass a concrete `networkId` for a per-network row, or
175
+ * `null` for the user's single global (profile-replacing) context row.
176
+ * Creates or updates the synthesized context paragraph + embedding.
177
+ */
178
+ upsertUserContext(params: {
179
+ userId: string;
180
+ networkId: string | null;
181
+ text: string;
182
+ embedding: number[];
183
+ premiseHash: string;
184
+ }): Promise<{
185
+ id: string;
186
+ }>;
187
+ /**
188
+ * Get the user context for a specific user+network pair, or the global row when
189
+ * `networkId` is `null`.
190
+ */
191
+ getUserContext(userId: string, networkId: string | null): Promise<{
192
+ id: string;
193
+ text: string;
194
+ embedding: number[];
195
+ premiseHash: string;
196
+ generatedAt: Date;
197
+ } | null>;
198
+ /**
199
+ * Get user contexts for a user across all their networks. Includes the global
200
+ * row (`networkId: null`) when present.
201
+ */
202
+ getUserContexts(userId: string): Promise<Array<{
203
+ id: string;
204
+ networkId: string | null;
205
+ text: string;
206
+ embedding: number[];
207
+ premiseHash: string;
208
+ generatedAt: Date;
209
+ }>>;
210
+ /**
211
+ * Cosine similarity search against intent embeddings using a context embedding.
212
+ * Restores the profile→intent cross-search deleted when Path B was removed.
213
+ */
214
+ searchIntentsByContextEmbedding(params: {
215
+ embedding: number[];
216
+ networkIds: string[];
217
+ excludeUserId: string;
218
+ limit: number;
219
+ minScore?: number;
220
+ }): Promise<Array<{
221
+ intentId: string;
222
+ userId: string;
223
+ networkId: string;
224
+ payload: string;
225
+ summary: string | null;
226
+ similarity: number;
227
+ }>>;
228
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Database operations for contacts, premises, and user contexts.
3
+ */
4
+ export {};
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Negotiation-specific persistence: continuation receipts, private
3
+ * consultations, and the queries the negotiation graph depends on.
4
+ */
5
+ import type { NegotiationOpportunityLifecycle, OpportunityStatus } from './database.entities.js';
6
+ import type { Database } from './database.port.js';
7
+ /**
8
+ * Negotiation-specific query operations not covered by generic
9
+ * conversation/task primitives.
10
+ */
11
+ /** A user's ordinary follow-up answer stored on established shared opportunity metadata. */
12
+ export interface NegotiationUserAnswer {
13
+ questionId: string;
14
+ selectedOptions: string[];
15
+ freeText?: string;
16
+ answeredAt: string;
17
+ }
18
+ export interface NegotiationPrivateConsultation {
19
+ recipientUserId: string;
20
+ recipientIntentId: string;
21
+ kind: 'answer' | 'dismiss' | 'timeout';
22
+ selectedOptions: string[];
23
+ freeText?: string;
24
+ }
25
+ export interface NegotiationContinuationExecution {
26
+ taskId: string;
27
+ settlementId: string;
28
+ opportunityId: string;
29
+ userId: string;
30
+ recipientIntentId: string;
31
+ networkId: string;
32
+ intentFingerprint: string;
33
+ opportunityStatus: string;
34
+ opportunityUpdatedAt: string;
35
+ counterpartyUserId: string;
36
+ counterpartyIntentId: string;
37
+ successorTaskId: string;
38
+ conversationId: string;
39
+ token: string;
40
+ fence: number;
41
+ leaseExpiresAt: string;
42
+ consultation: NegotiationPrivateConsultation;
43
+ }
44
+ export interface NegotiationContinuationReceipt {
45
+ priorTaskId: string;
46
+ settlementId: string;
47
+ successorTaskId: string;
48
+ fence: number;
49
+ outcome: 'accepted' | 'rejected' | 'stalled' | 'waiting_for_agent' | 'input_required';
50
+ }
51
+ export interface NegotiationQueries {
52
+ /** Capture canonical material binding before arming an ask-user timeout. */
53
+ captureNegotiationAskUserBinding(input: {
54
+ taskId: string;
55
+ turnContext: Record<string, unknown>;
56
+ settlementId: string;
57
+ recipientUserId: string;
58
+ recipientIntentId: string;
59
+ opportunityId: string;
60
+ networkId: string;
61
+ continuationExecution?: NegotiationContinuationExecution;
62
+ }): Promise<{
63
+ version: 2;
64
+ settlementId: string;
65
+ recipientUserId: string;
66
+ recipientIntentId: string;
67
+ opportunityId: string;
68
+ networkId: string;
69
+ intentFingerprint: string;
70
+ opportunityStatus: string;
71
+ opportunityUpdatedAt: string;
72
+ counterpartyUserId: string;
73
+ counterpartyIntentId: string;
74
+ }>;
75
+ /**
76
+ * Persists the full negotiation turn context (source/candidate user contexts,
77
+ * seed assessment, index context, discovery query) onto the task metadata so
78
+ * that polling agents can reconstruct the same context the system agent sees
79
+ * in-process. Merges into `metadata.turnContext`, leaving other keys intact.
80
+ * @param taskId - Task whose metadata to enrich
81
+ * @param turnContext - Absolute (source/candidate) view of the negotiation context
82
+ */
83
+ setTaskTurnContext(taskId: string, turnContext: Record<string, unknown>, continuationExecution?: NegotiationContinuationExecution): Promise<void>;
84
+ /**
85
+ * Merges a screen-gate decision (P2.1 shadow mode) into
86
+ * `metadata.screenDecision`, leaving other metadata keys intact. Optional so
87
+ * existing fakes/wireups remain valid; when absent the screen node logs the
88
+ * decision and proceeds without persisting.
89
+ * @param taskId - Task whose metadata to enrich
90
+ * @param screenDecision - ScreenDecisionRecord (decision, evidence, mode, timing)
91
+ */
92
+ setTaskScreenDecision?(taskId: string, screenDecision: Record<string, unknown>, continuationExecution?: NegotiationContinuationExecution): Promise<void>;
93
+ /**
94
+ * Merges an applied deadlock→bargaining shift record (IND-428) into
95
+ * `metadata.deadlockShift`, leaving other metadata keys intact. Internal
96
+ * analytics only — API surfaces must never project this key. Optional so
97
+ * existing fakes/wireups remain valid; when absent the turn node logs the
98
+ * shift and proceeds without persisting.
99
+ * @param taskId - Task whose metadata to enrich
100
+ * @param deadlockShift - DeadlockShiftRecord (run length, threshold, turn, seat, timing)
101
+ */
102
+ setTaskDeadlockShift?(taskId: string, deadlockShift: Record<string, unknown>, continuationExecution?: NegotiationContinuationExecution): Promise<void>;
103
+ /**
104
+ * Returns the most-recently-created task whose metadata carries
105
+ * `type: 'negotiation'` and `opportunityId: <id>`. Returns null if no
106
+ * negotiation has been started for that opportunity yet.
107
+ */
108
+ getNegotiationTaskForOpportunity(opportunityId: string): Promise<{
109
+ id: string;
110
+ conversationId: string;
111
+ state: string;
112
+ metadata: Record<string, unknown> | null;
113
+ createdAt: Date;
114
+ updatedAt: Date;
115
+ } | null>;
116
+ /**
117
+ * Returns the most-recently-created task whose metadata carries
118
+ * `type: 'negotiation'` on the given conversation, regardless of
119
+ * opportunityId or direction. Used by the init node's conversation-scoped
120
+ * tie-break: symmetric concurrent starts carry different opportunityIds, so
121
+ * the opportunity-scoped lookup above cannot see the competing task.
122
+ * Optional so existing fakes/wireups remain valid; when absent the
123
+ * tie-break is skipped (pre-stamp behavior).
124
+ */
125
+ getLatestNegotiationTaskForConversation?(conversationId: string): Promise<{
126
+ id: string;
127
+ conversationId: string;
128
+ state: string;
129
+ metadata: Record<string, unknown> | null;
130
+ createdAt: Date;
131
+ updatedAt: Date;
132
+ } | null>;
133
+ /**
134
+ * Returns user answers collected by the questioner system for a given
135
+ * opportunity. Reads `metadata.userAnswers` from the opportunities table.
136
+ * Used by the negotiation graph to inject between-session context into
137
+ * continuation prompts.
138
+ */
139
+ getOpportunityUserAnswers(opportunityId: string): Promise<NegotiationUserAnswer[]>;
140
+ }
141
+ /**
142
+ * Database dependency for the negotiation graph (A2A conversation/task/artifact
143
+ * persistence). Composes generic conversation ops with negotiation-specific queries.
144
+ *
145
+ * Access layer: ConversationDatabaseAdapter
146
+ */
147
+ export type NegotiationGraphDatabase = Pick<Database, 'getOrCreateDM' | 'getUserContext'> & NegotiationQueries & {
148
+ /**
149
+ * Update the status of an opportunity. Called from the negotiation graph to
150
+ * advance the opportunity lifecycle (negotiating -> pending/rejected/stalled).
151
+ * Returns only the narrow { id, status } needed by the graph, not the full Opportunity.
152
+ */
153
+ updateOpportunityStatus(id: string, status: OpportunityStatus, acceptedBy?: string, continuationExecution?: NegotiationContinuationExecution): Promise<{
154
+ id: string;
155
+ status: OpportunityStatus;
156
+ } | null>;
157
+ /** Persists a negotiation turn message within a conversation. */
158
+ createMessage(data: {
159
+ conversationId: string;
160
+ senderId: string;
161
+ role: 'user' | 'agent';
162
+ parts: unknown[];
163
+ taskId?: string;
164
+ metadata?: Record<string, unknown> | null;
165
+ continuationExecution?: NegotiationContinuationExecution;
166
+ }): Promise<{
167
+ id: string;
168
+ senderId: string;
169
+ role: 'user' | 'agent';
170
+ parts: unknown;
171
+ createdAt: Date;
172
+ }>;
173
+ /**
174
+ * Atomically claims an exact persisted opportunity attempt, promotes it to
175
+ * negotiating, and creates its task. Returns null when the status/version is
176
+ * stale or another qualifying task already owns the attempt.
177
+ */
178
+ createNegotiationTaskForAttempt(input: {
179
+ conversationId: string;
180
+ opportunityId: string;
181
+ expectedStatus: OpportunityStatus;
182
+ expectedUpdatedAt: Date;
183
+ metadata: Record<string, unknown>;
184
+ }): Promise<{
185
+ id: string;
186
+ conversationId: string;
187
+ state: string;
188
+ } | null>;
189
+ /** Creates a generic task to track a non-attempt-bound lifecycle. */
190
+ createTask(conversationId: string, metadata?: Record<string, unknown>): Promise<{
191
+ id: string;
192
+ conversationId: string;
193
+ state: string;
194
+ }>;
195
+ /**
196
+ * Under a deterministic settlement lock, validate the exact canceled ask_user
197
+ * task and return its existing successor or create one. Never consults a
198
+ * latest-task lookup.
199
+ */
200
+ getOrCreateNegotiationContinuationTask(input: {
201
+ priorTaskId: string;
202
+ settlementId: string;
203
+ conversationId: string;
204
+ opportunityId: string;
205
+ metadata: Record<string, unknown>;
206
+ }): Promise<{
207
+ id: string;
208
+ conversationId: string;
209
+ state: string;
210
+ created: boolean;
211
+ } | null>;
212
+ /** Transitions a task to a new state (e.g. working, completed, failed). */
213
+ updateTaskState(taskId: string, state: string, statusMessage?: unknown, continuationExecution?: NegotiationContinuationExecution, parkGeneration?: string): Promise<{
214
+ id: string;
215
+ conversationId: string;
216
+ state: string;
217
+ }>;
218
+ /** Persists a negotiation outcome artifact attached to a task. */
219
+ createArtifact(data: {
220
+ taskId: string;
221
+ name?: string;
222
+ parts: unknown[];
223
+ metadata?: Record<string, unknown> | null;
224
+ continuationExecution?: NegotiationContinuationExecution;
225
+ }): Promise<{
226
+ id: string;
227
+ }>;
228
+ /** Lists negotiation tasks where the given user is source or candidate. */
229
+ getTasksForUser(userId: string, options?: {
230
+ state?: string;
231
+ }): Promise<Array<{
232
+ id: string;
233
+ conversationId: string;
234
+ state: string;
235
+ metadata: Record<string, unknown> | null;
236
+ createdAt: Date;
237
+ updatedAt: Date;
238
+ }>>;
239
+ /**
240
+ * Resolves each opportunity to the intent carried by the given user's actor.
241
+ * Missing opportunities or actor intents are returned as null so callers can
242
+ * enforce fail-closed scope filtering for legacy task metadata.
243
+ */
244
+ getIntentIdsForOpportunities(opportunityIds: string[], userId: string): Promise<Record<string, string | null>>;
245
+ /**
246
+ * Batch-loads current opportunity lifecycle evidence for negotiation
247
+ * narration. Implementations must omit opportunities that do not contain the
248
+ * authenticated owner actor. Optional for backward-compatible hosts; callers
249
+ * must treat a missing implementation as unavailable evidence, never as acceptance.
250
+ */
251
+ getOpportunityLifecyclesForNegotiations?(opportunityIds: string[], ownerUserId: string): Promise<Record<string, NegotiationOpportunityLifecycle>>;
252
+ /** Gets a specific task by ID. */
253
+ getTask(taskId: string): Promise<{
254
+ id: string;
255
+ conversationId: string;
256
+ state: string;
257
+ metadata: Record<string, unknown> | null;
258
+ createdAt: Date;
259
+ updatedAt: Date;
260
+ } | null>;
261
+ /**
262
+ * Gets all messages for a conversation, ordered by creation time.
263
+ *
264
+ * `taskId` is the originating negotiation task (IND-569). Optional so legacy
265
+ * hosts remain valid; when omitted, prior negotiation turns cannot be
266
+ * attributed to their opportunity and degrade to the unattributed
267
+ * prior-dialogue block rather than being mixed into the current opportunity.
268
+ */
269
+ getMessagesForConversation(conversationId: string): Promise<Array<{
270
+ id: string;
271
+ senderId: string;
272
+ role: 'user' | 'agent';
273
+ parts: unknown[];
274
+ createdAt: Date;
275
+ taskId?: string | null;
276
+ }>>;
277
+ /** Gets artifacts for a task (e.g. negotiation outcome). */
278
+ getArtifactsForTask(taskId: string): Promise<Array<{
279
+ id: string;
280
+ name: string | null;
281
+ parts: unknown[];
282
+ metadata: Record<string, unknown> | null;
283
+ }>>;
284
+ };
285
+ /**
286
+ * Database interface for opportunity controller (API).
287
+ *
288
+ * Access layer: Both UserDatabase + SystemDatabase (API handles auth)
289
+ */
290
+ /**
291
+ * Optional atomic outbox for Lens B outcome capture (IND-434). Passed to a
292
+ * winning owner-action transition so the append-only outcome event is written
293
+ * in the SAME transaction as the status change:
294
+ * - a rolled-back action leaves NO event;
295
+ * - a committed eligible action produces EXACTLY one event;
296
+ * - `result.inserted` is set to true by the adapter only when a NEW row was
297
+ * written (idempotent retries / duplicates set it false), so the caller can
298
+ * gate post-commit mining on a genuine first insert.
299
+ *
300
+ * `event` is typed `unknown` (the api-side outcome-event insert row, cast by the
301
+ * adapter) to keep the protocol layer free of database-schema imports. The
302
+ * actor-resolution mode is a transaction-time precondition: selected-intent
303
+ * captures require that exact actor intent, while unscoped captures require the
304
+ * recipient to still have one unambiguous actor-intent scope.
305
+ */
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Negotiation-specific persistence: continuation receipts, private
3
+ * consultations, and the queries the negotiation graph depends on.
4
+ */
5
+ export {};
6
+ /**
7
+ * Database interface for opportunity controller (API).
8
+ *
9
+ * Access layer: Both UserDatabase + SystemDatabase (API handles auth)
10
+ */
11
+ /**
12
+ * Optional atomic outbox for Lens B outcome capture (IND-434). Passed to a
13
+ * winning owner-action transition so the append-only outcome event is written
14
+ * in the SAME transaction as the status change:
15
+ * - a rolled-back action leaves NO event;
16
+ * - a committed eligible action produces EXACTLY one event;
17
+ * - `result.inserted` is set to true by the adapter only when a NEW row was
18
+ * written (idempotent retries / duplicates set it false), so the caller can
19
+ * gate post-commit mining on a genuine first insert.
20
+ *
21
+ * `event` is typed `unknown` (the api-side outcome-event insert row, cast by the
22
+ * adapter) to keep the protocol layer free of database-schema imports. The
23
+ * actor-resolution mode is a transaction-time precondition: selected-intent
24
+ * captures require that exact actor intent, while unscoped captures require the
25
+ * recipient to still have one unambiguous actor-intent scope.
26
+ */