@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
@@ -21,167 +21,16 @@ const FRESHNESS_WINDOW_MS = 12 * 60 * 60 * 1000; // 12 hours
21
21
  */
22
22
  export class MaintenanceGraphFactory {
23
23
  constructor(database, cache, queue) {
24
- this.database = database;
25
- this.cache = cache;
26
- this.queue = queue;
24
+ this.deps = { database, cache, queue };
27
25
  }
28
26
  /** Compile and return the maintenance graph. */
29
27
  createGraph() {
30
- const loadCurrentRadarNode = async (state) => {
31
- if (!state.userId) {
32
- return { error: 'userId is required' };
33
- }
34
- try {
35
- const raw = await this.database.getOpportunitiesForUser(state.userId, { limit: 150 });
36
- const actionable = raw.filter((opp) => isActionableForViewer(opp.actors, opp.status, state.userId));
37
- const expired = raw.filter((opp) => opp.status === 'expired' && canUserSeeOpportunity(opp.actors, opp.status, state.userId));
38
- const activeIntents = await this.database.getActiveIntents(state.userId);
39
- // Read last rediscovery timestamp from cache
40
- let lastRediscoveryAt = null;
41
- try {
42
- const cached = await this.cache.get(`rediscovery:lastRun:${state.userId}`);
43
- if (typeof cached?.triggeredAt === 'string') {
44
- const parsed = Date.parse(cached.triggeredAt);
45
- if (Number.isFinite(parsed)) {
46
- lastRediscoveryAt = parsed;
47
- }
48
- }
49
- }
50
- catch {
51
- // Cache unavailable — treat as no data
52
- }
53
- return {
54
- currentOpportunities: actionable,
55
- expiredCount: expired.length,
56
- activeIntents: activeIntents ?? [],
57
- lastRediscoveryAt,
58
- };
59
- }
60
- catch (e) {
61
- logger.error('MaintenanceGraph loadCurrentRadar failed', { error: e });
62
- return { error: 'Failed to load current radar' };
63
- }
64
- };
65
- const scoreRadarHealthNode = async (state) => {
66
- if (state.error)
67
- return {};
68
- try {
69
- const opps = state.currentOpportunities ?? [];
70
- let connectionCount = 0;
71
- let connectorFlowCount = 0;
72
- for (const opp of opps) {
73
- const category = classifyOpportunity(opp, state.userId);
74
- if (category === 'connection')
75
- connectionCount++;
76
- else if (category === 'connector-flow')
77
- connectorFlowCount++;
78
- }
79
- const healthResult = computeRadarHealth({
80
- connectionCount,
81
- connectorFlowCount,
82
- expiredCount: state.expiredCount,
83
- totalActionable: opps.length,
84
- lastRediscoveryAt: state.lastRediscoveryAt,
85
- freshnessWindowMs: FRESHNESS_WINDOW_MS,
86
- });
87
- logger.verbose('Radar health scored', {
88
- userId: state.userId,
89
- score: healthResult.score,
90
- shouldMaintain: healthResult.shouldMaintain,
91
- connectorFlowCount,
92
- });
93
- return { healthResult, connectorFlowCount };
94
- }
95
- catch (e) {
96
- logger.error('MaintenanceGraph scoreRadarHealth failed', { error: e });
97
- return { error: 'Failed to score radar health' };
98
- }
99
- };
100
- const shouldRediscover = (state) => {
101
- if (state.error)
102
- return 'introducerDiscovery';
103
- if (state.healthResult?.shouldMaintain && state.activeIntents.length > 0) {
104
- return 'rediscover';
105
- }
106
- return 'introducerDiscovery';
107
- };
108
- const rediscoverNode = async (state) => {
109
- try {
110
- const bucket = Math.floor(Date.now() / (6 * 60 * 60 * 1000));
111
- const results = await Promise.allSettled(state.activeIntents.map((intent) => this.queue.addJob({ intentId: intent.id, userId: state.userId }, { priority: 10, jobId: `rediscovery-${state.userId}-${intent.id}-${bucket}` })));
112
- for (const r of results) {
113
- if (r.status === 'rejected') {
114
- const errMsg = r.reason instanceof Error ? r.reason.message : String(r.reason);
115
- logger.error('Rediscovery job enqueue failed', { error: errMsg });
116
- }
117
- }
118
- const enqueued = results.filter((r) => r.status === 'fulfilled').length;
119
- // Record last run timestamp
120
- if (enqueued > 0) {
121
- try {
122
- await this.cache.set(`rediscovery:lastRun:${state.userId}`, { triggeredAt: new Date().toISOString() }, { ttl: 24 * 60 * 60 });
123
- }
124
- catch {
125
- // Cache write failure is non-fatal
126
- }
127
- }
128
- return { rediscoveryJobsEnqueued: enqueued };
129
- }
130
- catch (e) {
131
- logger.error('MaintenanceGraph rediscover failed', { error: e });
132
- return { error: 'Failed to enqueue rediscovery jobs' };
133
- }
134
- };
135
- const introducerDiscoveryNode = async (state) => {
136
- if (!isIntroducerDiscoveryEnabled()) {
137
- logger.info('Introducer discovery skipped — disabled by configuration', {
138
- userId: state.userId,
139
- });
140
- return {};
141
- }
142
- try {
143
- const connectorFlowTarget = RADAR_SOFT_TARGETS.connectorFlow;
144
- if (!shouldRunIntroducerDiscovery(state.connectorFlowCount, connectorFlowTarget)) {
145
- logger.verbose('Introducer discovery skipped — connector-flow target met', {
146
- userId: state.userId,
147
- connectorFlowCount: state.connectorFlowCount,
148
- connectorFlowTarget,
149
- });
150
- return {};
151
- }
152
- // Cast database/queue to introducer discovery interfaces (they are compatible)
153
- const result = await runIntroducerDiscovery(this.database, this.queue, state.userId);
154
- logger.info('Introducer discovery complete', {
155
- userId: state.userId,
156
- contactsEvaluated: result.contactsEvaluated,
157
- jobsEnqueued: result.jobsEnqueued,
158
- skippedReason: result.skippedReason,
159
- });
160
- return { introducerDiscoveryJobsEnqueued: result.jobsEnqueued };
161
- }
162
- catch (e) {
163
- logger.error('MaintenanceGraph introducerDiscovery failed', { error: e });
164
- // Non-fatal: do not set error, just log and continue
165
- return {};
166
- }
167
- };
168
- const logMaintenanceNode = async (state) => {
169
- logger.info('Maintenance complete', {
170
- userId: state.userId,
171
- score: state.healthResult?.score,
172
- shouldMaintain: state.healthResult?.shouldMaintain,
173
- rediscoveryJobs: state.rediscoveryJobsEnqueued,
174
- introducerDiscoveryJobs: state.introducerDiscoveryJobsEnqueued,
175
- activeIntents: state.activeIntents.length,
176
- connectorFlowCount: state.connectorFlowCount,
177
- });
178
- return {};
179
- };
28
+ const deps = this.deps;
180
29
  const graph = new StateGraph(MaintenanceGraphState)
181
- .addNode('loadCurrentRadar', loadCurrentRadarNode)
30
+ .addNode('loadCurrentRadar', (state) => loadCurrentRadarNode(state, deps))
182
31
  .addNode('scoreRadarHealth', scoreRadarHealthNode)
183
- .addNode('rediscover', rediscoverNode)
184
- .addNode('introducerDiscovery', introducerDiscoveryNode)
32
+ .addNode('rediscover', (state) => rediscoverNode(state, deps))
33
+ .addNode('introducerDiscovery', (state) => introducerDiscoveryNode(state, deps))
185
34
  .addNode('logMaintenance', logMaintenanceNode)
186
35
  .addEdge(START, 'loadCurrentRadar')
187
36
  .addConditionalEdges('loadCurrentRadar', (state) => (state.error ? 'end' : 'scoreRadarHealth'), {
@@ -198,3 +47,153 @@ export class MaintenanceGraphFactory {
198
47
  return graph.compile();
199
48
  }
200
49
  }
50
+ export async function loadCurrentRadarNode(state, deps) {
51
+ if (!state.userId) {
52
+ return { error: 'userId is required' };
53
+ }
54
+ try {
55
+ const raw = await deps.database.getOpportunitiesForUser(state.userId, { limit: 150 });
56
+ const actionable = raw.filter((opp) => isActionableForViewer(opp.actors, opp.status, state.userId));
57
+ const expired = raw.filter((opp) => opp.status === 'expired' && canUserSeeOpportunity(opp.actors, opp.status, state.userId));
58
+ const activeIntents = await deps.database.getActiveIntents(state.userId);
59
+ // Read last rediscovery timestamp from cache
60
+ let lastRediscoveryAt = null;
61
+ try {
62
+ const cached = await deps.cache.get(`rediscovery:lastRun:${state.userId}`);
63
+ if (typeof cached?.triggeredAt === 'string') {
64
+ const parsed = Date.parse(cached.triggeredAt);
65
+ if (Number.isFinite(parsed)) {
66
+ lastRediscoveryAt = parsed;
67
+ }
68
+ }
69
+ }
70
+ catch {
71
+ // Cache unavailable — treat as no data
72
+ }
73
+ return {
74
+ currentOpportunities: actionable,
75
+ expiredCount: expired.length,
76
+ activeIntents: activeIntents ?? [],
77
+ lastRediscoveryAt,
78
+ };
79
+ }
80
+ catch (e) {
81
+ logger.error('MaintenanceGraph loadCurrentRadar failed', { error: e });
82
+ return { error: 'Failed to load current radar' };
83
+ }
84
+ }
85
+ export async function scoreRadarHealthNode(state) {
86
+ if (state.error)
87
+ return {};
88
+ try {
89
+ const opps = state.currentOpportunities ?? [];
90
+ let connectionCount = 0;
91
+ let connectorFlowCount = 0;
92
+ for (const opp of opps) {
93
+ const category = classifyOpportunity(opp, state.userId);
94
+ if (category === 'connection')
95
+ connectionCount++;
96
+ else if (category === 'connector-flow')
97
+ connectorFlowCount++;
98
+ }
99
+ const healthResult = computeRadarHealth({
100
+ connectionCount,
101
+ connectorFlowCount,
102
+ expiredCount: state.expiredCount,
103
+ totalActionable: opps.length,
104
+ lastRediscoveryAt: state.lastRediscoveryAt,
105
+ freshnessWindowMs: FRESHNESS_WINDOW_MS,
106
+ });
107
+ logger.verbose('Radar health scored', {
108
+ userId: state.userId,
109
+ score: healthResult.score,
110
+ shouldMaintain: healthResult.shouldMaintain,
111
+ connectorFlowCount,
112
+ });
113
+ return { healthResult, connectorFlowCount };
114
+ }
115
+ catch (e) {
116
+ logger.error('MaintenanceGraph scoreRadarHealth failed', { error: e });
117
+ return { error: 'Failed to score radar health' };
118
+ }
119
+ }
120
+ export function shouldRediscover(state) {
121
+ if (state.error)
122
+ return 'introducerDiscovery';
123
+ if (state.healthResult?.shouldMaintain && state.activeIntents.length > 0) {
124
+ return 'rediscover';
125
+ }
126
+ return 'introducerDiscovery';
127
+ }
128
+ export async function rediscoverNode(state, deps) {
129
+ try {
130
+ const bucket = Math.floor(Date.now() / (6 * 60 * 60 * 1000));
131
+ const results = await Promise.allSettled(state.activeIntents.map((intent) => deps.queue.addJob({ intentId: intent.id, userId: state.userId }, { priority: 10, jobId: `rediscovery-${state.userId}-${intent.id}-${bucket}` })));
132
+ for (const r of results) {
133
+ if (r.status === 'rejected') {
134
+ const errMsg = r.reason instanceof Error ? r.reason.message : String(r.reason);
135
+ logger.error('Rediscovery job enqueue failed', { error: errMsg });
136
+ }
137
+ }
138
+ const enqueued = results.filter((r) => r.status === 'fulfilled').length;
139
+ // Record last run timestamp
140
+ if (enqueued > 0) {
141
+ try {
142
+ await deps.cache.set(`rediscovery:lastRun:${state.userId}`, { triggeredAt: new Date().toISOString() }, { ttl: 24 * 60 * 60 });
143
+ }
144
+ catch {
145
+ // Cache write failure is non-fatal
146
+ }
147
+ }
148
+ return { rediscoveryJobsEnqueued: enqueued };
149
+ }
150
+ catch (e) {
151
+ logger.error('MaintenanceGraph rediscover failed', { error: e });
152
+ return { error: 'Failed to enqueue rediscovery jobs' };
153
+ }
154
+ }
155
+ export async function introducerDiscoveryNode(state, deps) {
156
+ if (!isIntroducerDiscoveryEnabled()) {
157
+ logger.info('Introducer discovery skipped — disabled by configuration', {
158
+ userId: state.userId,
159
+ });
160
+ return {};
161
+ }
162
+ try {
163
+ const connectorFlowTarget = RADAR_SOFT_TARGETS.connectorFlow;
164
+ if (!shouldRunIntroducerDiscovery(state.connectorFlowCount, connectorFlowTarget)) {
165
+ logger.verbose('Introducer discovery skipped — connector-flow target met', {
166
+ userId: state.userId,
167
+ connectorFlowCount: state.connectorFlowCount,
168
+ connectorFlowTarget,
169
+ });
170
+ return {};
171
+ }
172
+ // Cast database/queue to introducer discovery interfaces (they are compatible)
173
+ const result = await runIntroducerDiscovery(deps.database, deps.queue, state.userId);
174
+ logger.info('Introducer discovery complete', {
175
+ userId: state.userId,
176
+ contactsEvaluated: result.contactsEvaluated,
177
+ jobsEnqueued: result.jobsEnqueued,
178
+ skippedReason: result.skippedReason,
179
+ });
180
+ return { introducerDiscoveryJobsEnqueued: result.jobsEnqueued };
181
+ }
182
+ catch (e) {
183
+ logger.error('MaintenanceGraph introducerDiscovery failed', { error: e });
184
+ // Non-fatal: do not set error, just log and continue
185
+ return {};
186
+ }
187
+ }
188
+ export async function logMaintenanceNode(state) {
189
+ logger.info('Maintenance complete', {
190
+ userId: state.userId,
191
+ score: state.healthResult?.score,
192
+ shouldMaintain: state.healthResult?.shouldMaintain,
193
+ rediscoveryJobs: state.rediscoveryJobsEnqueued,
194
+ introducerDiscoveryJobs: state.introducerDiscoveryJobsEnqueued,
195
+ activeIntents: state.activeIntents.length,
196
+ connectorFlowCount: state.connectorFlowCount,
197
+ });
198
+ return {};
199
+ }
@@ -13,10 +13,10 @@ export declare const McpToolPermissionRequirementSchema: z.ZodObject<{
13
13
  */
14
14
  reach: z.ZodDefault<z.ZodEnum<["principal", "network"]>>;
15
15
  }, "strict", z.ZodTypeAny, {
16
- action: "manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks";
16
+ action: "manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks";
17
17
  reach: "network" | "principal";
18
18
  }, {
19
- action: "manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks";
19
+ action: "manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks";
20
20
  reach?: "network" | "principal" | undefined;
21
21
  }>;
22
22
  export type McpToolPermissionRequirement = z.infer<typeof McpToolPermissionRequirementSchema>;
@@ -38,19 +38,19 @@ export declare const McpToolAccessRuleSchema: z.ZodEffects<z.ZodObject<{
38
38
  }, "strict", z.ZodTypeAny, {
39
39
  reach: "network" | "principal";
40
40
  access: "removed" | "permission" | "authenticated" | "human_only" | "agent_admin" | "informational" | "delivery_only";
41
- actions?: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
41
+ actions?: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
42
42
  }, {
43
43
  reach: "network" | "principal";
44
44
  access: "removed" | "permission" | "authenticated" | "human_only" | "agent_admin" | "informational" | "delivery_only";
45
- actions?: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
45
+ actions?: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
46
46
  }>, {
47
47
  reach: "network" | "principal";
48
48
  access: "removed" | "permission" | "authenticated" | "human_only" | "agent_admin" | "informational" | "delivery_only";
49
- actions?: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
49
+ actions?: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
50
50
  }, {
51
51
  reach: "network" | "principal";
52
52
  access: "removed" | "permission" | "authenticated" | "human_only" | "agent_admin" | "informational" | "delivery_only";
53
- actions?: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
53
+ actions?: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[] | undefined;
54
54
  }>;
55
55
  export type McpToolAccessRule = z.infer<typeof McpToolAccessRuleSchema>;
56
56
  export type McpToolAccessRuleMap = ReadonlyMap<string, McpToolAccessRule>;
@@ -63,7 +63,7 @@ export declare function defineMcpToolAccessRules(rules: Readonly<Record<string,
63
63
  * retain domain ownership, membership, exact-scope, and approval checks.
64
64
  */
65
65
  export declare const CANONICAL_MCP_TOOL_ACCESS_RULES: McpToolAccessRuleMap;
66
- /** Tools visible while a session-authenticated human completes onboarding. */
66
+ /** Tools visible on the REST Tool API while web/CLI onboarding is incomplete. MCP does not use this allowlist. */
67
67
  export declare const ONBOARDING_ALLOWED: ReadonlySet<string>;
68
68
  /** Agent administration inventory. */
69
69
  export declare const MCP_AGENT_ADMIN_TOOLS: ReadonlySet<string>;
@@ -84,72 +84,68 @@ export declare const McpPolicyAgentSnapshotSchema: z.ZodObject<{
84
84
  userId: string;
85
85
  scope: "network" | "global" | "node";
86
86
  scopeId: string | null;
87
- agentId: string;
88
87
  actions: string[];
88
+ agentId: string;
89
89
  }, {
90
90
  userId: string;
91
91
  scope: "network" | "global" | "node";
92
92
  scopeId: string | null;
93
- agentId: string;
94
93
  actions: string[];
94
+ agentId: string;
95
95
  }>, "many">;
96
96
  }, "strict", z.ZodTypeAny, {
97
97
  id: string;
98
98
  type: "system" | "personal" | "external";
99
99
  status: "active" | "inactive";
100
- ownerId: string;
101
100
  permissions: {
102
101
  userId: string;
103
102
  scope: "network" | "global" | "node";
104
103
  scopeId: string | null;
105
- agentId: string;
106
104
  actions: string[];
105
+ agentId: string;
107
106
  }[];
107
+ ownerId: string;
108
108
  }, {
109
109
  id: string;
110
110
  type: "system" | "personal" | "external";
111
111
  status: "active" | "inactive";
112
- ownerId: string;
113
112
  permissions: {
114
113
  userId: string;
115
114
  scope: "network" | "global" | "node";
116
115
  scopeId: string | null;
117
- agentId: string;
118
116
  actions: string[];
117
+ agentId: string;
119
118
  }[];
119
+ ownerId: string;
120
120
  }>;
121
121
  export type McpPolicyAgentSnapshot = z.infer<typeof McpPolicyAgentSnapshotSchema>;
122
- export declare const McpPrincipalProfileSchema: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
122
+ export declare const McpPrincipalProfileSchema: z.ZodEnum<["session_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
123
123
  export type McpPrincipalProfile = z.infer<typeof McpPrincipalProfileSchema>;
124
124
  export declare const McpCapabilitySubjectSchema: z.ZodObject<{
125
- profile: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
125
+ profile: z.ZodEnum<["session_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
126
126
  userId: z.ZodString;
127
127
  agentId: z.ZodOptional<z.ZodString>;
128
128
  agentType: z.ZodOptional<z.ZodEnum<["personal", "external", "system"]>>;
129
- isOnboarding: z.ZodBoolean;
130
129
  networkScopeId: z.ZodNullable<z.ZodString>;
131
130
  permissions: z.ZodArray<z.ZodEnum<["manage:identity", "manage:premises", "manage:intents", "manage:networks", "manage:opportunities", "manage:negotiations"]>, "many">;
132
131
  }, "strict", z.ZodTypeAny, {
133
132
  userId: string;
134
- profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
135
- permissions: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[];
133
+ profile: "session_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
134
+ permissions: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[];
136
135
  networkScopeId: string | null;
137
- isOnboarding: boolean;
138
136
  agentId?: string | undefined;
139
137
  agentType?: "system" | "personal" | "external" | undefined;
140
138
  }, {
141
139
  userId: string;
142
- profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
143
- permissions: ("manage:intents" | "manage:opportunities" | "manage:negotiations" | "manage:identity" | "manage:premises" | "manage:networks")[];
140
+ profile: "session_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
141
+ permissions: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[];
144
142
  networkScopeId: string | null;
145
- isOnboarding: boolean;
146
143
  agentId?: string | undefined;
147
144
  agentType?: "system" | "personal" | "external" | undefined;
148
145
  }>;
149
146
  export type McpCapabilitySubject = z.infer<typeof McpCapabilitySubjectSchema>;
150
147
  export type ResolveMcpCapabilitySubjectInput = {
151
148
  identity: McpResolvedIdentity;
152
- isOnboarding: boolean;
153
149
  agent?: McpPolicyAgentSnapshot | null;
154
150
  };
155
151
  /**
@@ -166,13 +162,13 @@ export declare function projectStoredPermissionActions(actions: readonly string[
166
162
  export declare function resolveMcpCapabilitySubject(input: ResolveMcpCapabilitySubjectInput): McpCapabilitySubject;
167
163
  /**
168
164
  * Maps a resolved capability subject to the typed caller context consumed by
169
- * the centralized activity-summary projection. Session and onboarding humans
170
- * own the summarized data and receive the full owner view; every other
171
- * profile is projected as an agent bounded by its granted permissions and
172
- * (for network agents) its bound community.
165
+ * the centralized activity-summary projection. Session humans own the
166
+ * summarized data and receive the full owner view; every other profile is
167
+ * projected as an agent bounded by its granted permissions and (for network
168
+ * agents) its bound community.
173
169
  */
174
170
  export declare function resolveMcpActivityCaller(subject: McpCapabilitySubject): McpActivityCaller;
175
- export declare const McpCapabilityDecisionReasonSchema: z.ZodEnum<["session_human", "onboarding", "enrollment", "authenticated", "agent_self_read", "informational", "permission_granted", "delivery", "onboarding_required", "enrollment_required", "unregistered_principal", "invalid_agent", "agent_admin_denied", "human_read_own_agent_denied", "human_only", "permission_missing", "delivery_required", "removed", "tool_unclassified"]>;
171
+ export declare const McpCapabilityDecisionReasonSchema: z.ZodEnum<["session_human", "enrollment", "authenticated", "agent_self_read", "informational", "permission_granted", "delivery", "enrollment_required", "unregistered_principal", "invalid_agent", "agent_admin_denied", "human_read_own_agent_denied", "human_only", "permission_missing", "delivery_required", "removed", "tool_unclassified"]>;
176
172
  export type McpCapabilityDecision = {
177
173
  allowed: boolean;
178
174
  reason: z.infer<typeof McpCapabilityDecisionReasonSchema>;
@@ -113,7 +113,6 @@ export const CANONICAL_MCP_TOOL_ACCESS_RULES = defineMcpToolAccessRules({
113
113
  update_user_context: { access: 'permission', actions: ['manage:identity'], reach: 'principal' },
114
114
  get_enrichment_run: { access: 'permission', actions: ['manage:identity'], reach: 'principal' },
115
115
  cancel_enrichment_run: { access: 'permission', actions: ['manage:identity'], reach: 'principal' },
116
- complete_onboarding: { access: 'human_only', reach: 'principal' },
117
116
  // Premises are meta-network; a network-scoped agent retains principal reach.
118
117
  read_premises: { access: 'permission', actions: ['manage:premises'], reach: 'principal' },
119
118
  create_premise: { access: 'permission', actions: ['manage:premises'], reach: 'principal' },
@@ -204,7 +203,7 @@ export const CANONICAL_MCP_TOOL_ACCESS_RULES = defineMcpToolAccessRules({
204
203
  // unknown before any authorization work. read_activity_summary (above) is
205
204
  // the only public activity-reporting name; no legacy alias is retained.
206
205
  });
207
- /** Tools visible while a session-authenticated human completes onboarding. */
206
+ /** Tools visible on the REST Tool API while web/CLI onboarding is incomplete. MCP does not use this allowlist. */
208
207
  export const ONBOARDING_ALLOWED = new Set([
209
208
  'register_agent',
210
209
  'read_docs',
@@ -249,7 +248,6 @@ export const McpPolicyAgentSnapshotSchema = z.object({
249
248
  }).strict();
250
249
  export const McpPrincipalProfileSchema = z.enum([
251
250
  'session_human',
252
- 'onboarding_human',
253
251
  'enrollment_key',
254
252
  'unregistered_key',
255
253
  'registered_global_agent',
@@ -263,7 +261,6 @@ export const McpCapabilitySubjectSchema = z.object({
263
261
  userId: z.string().min(1),
264
262
  agentId: z.string().min(1).optional(),
265
263
  agentType: z.enum(['personal', 'external', 'system']).optional(),
266
- isOnboarding: z.boolean(),
267
264
  networkScopeId: z.string().min(1).nullable(),
268
265
  permissions: z.array(McpPermissionActionSchema),
269
266
  }).strict();
@@ -336,12 +333,11 @@ function resolveAgentPermissions(identity, agent) {
336
333
  * Resolves a request-local, runtime-validated principal profile.
337
334
  */
338
335
  export function resolveMcpCapabilitySubject(input) {
339
- const { identity, isOnboarding } = input;
336
+ const { identity } = input;
340
337
  if (identity.isSessionAuth === true) {
341
338
  return McpCapabilitySubjectSchema.parse({
342
- profile: isOnboarding ? 'onboarding_human' : 'session_human',
339
+ profile: 'session_human',
343
340
  userId: identity.userId,
344
- isOnboarding,
345
341
  networkScopeId: null,
346
342
  permissions: [],
347
343
  });
@@ -350,7 +346,6 @@ export function resolveMcpCapabilitySubject(input) {
350
346
  return McpCapabilitySubjectSchema.parse({
351
347
  profile: identity.enrollmentCapable === true ? 'enrollment_key' : 'unregistered_key',
352
348
  userId: identity.userId,
353
- isOnboarding,
354
349
  networkScopeId: null,
355
350
  permissions: [],
356
351
  });
@@ -364,7 +359,6 @@ export function resolveMcpCapabilitySubject(input) {
364
359
  profile: 'invalid_agent',
365
360
  userId: identity.userId,
366
361
  agentId: identity.agentId,
367
- isOnboarding,
368
362
  networkScopeId: identity.networkScopeId ?? null,
369
363
  permissions: [],
370
364
  });
@@ -382,20 +376,19 @@ export function resolveMcpCapabilitySubject(input) {
382
376
  userId: identity.userId,
383
377
  agentId: identity.agentId,
384
378
  agentType: agent.type,
385
- isOnboarding,
386
379
  networkScopeId: identity.networkScopeId ?? null,
387
380
  permissions: resolveAgentPermissions(identity, agent),
388
381
  });
389
382
  }
390
383
  /**
391
384
  * Maps a resolved capability subject to the typed caller context consumed by
392
- * the centralized activity-summary projection. Session and onboarding humans
393
- * own the summarized data and receive the full owner view; every other
394
- * profile is projected as an agent bounded by its granted permissions and
395
- * (for network agents) its bound community.
385
+ * the centralized activity-summary projection. Session humans own the
386
+ * summarized data and receive the full owner view; every other profile is
387
+ * projected as an agent bounded by its granted permissions and (for network
388
+ * agents) its bound community.
396
389
  */
397
390
  export function resolveMcpActivityCaller(subject) {
398
- const isHuman = subject.profile === 'session_human' || subject.profile === 'onboarding_human';
391
+ const isHuman = subject.profile === 'session_human';
399
392
  return McpActivityCallerSchema.parse({
400
393
  kind: isHuman ? 'human' : 'agent',
401
394
  permissions: isHuman ? [] : subject.permissions,
@@ -404,14 +397,12 @@ export function resolveMcpActivityCaller(subject) {
404
397
  }
405
398
  export const McpCapabilityDecisionReasonSchema = z.enum([
406
399
  'session_human',
407
- 'onboarding',
408
400
  'enrollment',
409
401
  'authenticated',
410
402
  'agent_self_read',
411
403
  'informational',
412
404
  'permission_granted',
413
405
  'delivery',
414
- 'onboarding_required',
415
406
  'enrollment_required',
416
407
  'unregistered_principal',
417
408
  'invalid_agent',
@@ -475,9 +466,6 @@ export class McpCapabilityPolicy {
475
466
  ? { allowed: true, reason: 'enrollment', reach: rule.reach }
476
467
  : { allowed: false, reason: 'enrollment_required', reach: rule.reach };
477
468
  }
478
- if (subject.isOnboarding && !ONBOARDING_ALLOWED.has(toolName)) {
479
- return { allowed: false, reason: 'onboarding_required', reach: rule.reach };
480
- }
481
469
  if (subject.profile === 'hermes_agent') {
482
470
  const requirement = HERMES_AGENT_MCP_TOOL_PERMISSIONS.get(toolName);
483
471
  if (!requirement)
@@ -516,27 +504,19 @@ export class McpCapabilityPolicy {
516
504
  ? { allowed: true, reason: 'agent_self_read', reach: rule.reach }
517
505
  : { allowed: false, reason: 'agent_admin_denied', reach: rule.reach };
518
506
  }
519
- // Session/onboarding humans get every agent_admin tool EXCEPT
520
- // read_own_agent, which is reserved for agent principals.
521
- if (subject.profile === 'session_human' || subject.profile === 'onboarding_human') {
507
+ // Session humans get every agent_admin tool EXCEPT read_own_agent,
508
+ // which is reserved for agent principals.
509
+ if (subject.profile === 'session_human') {
522
510
  return toolName === 'read_own_agent'
523
511
  ? { allowed: false, reason: 'human_read_own_agent_denied', reach: rule.reach }
524
- : {
525
- allowed: true,
526
- reason: subject.profile === 'onboarding_human' ? 'onboarding' : 'session_human',
527
- reach: rule.reach,
528
- };
512
+ : { allowed: true, reason: 'session_human', reach: rule.reach };
529
513
  }
530
514
  // Every other profile (enrollment/unregistered/invalid) is handled above
531
515
  // and never reaches here; fail closed for completeness.
532
516
  return { allowed: false, reason: 'agent_admin_denied', reach: rule.reach };
533
517
  }
534
- if (subject.profile === 'session_human' || subject.profile === 'onboarding_human') {
535
- return {
536
- allowed: true,
537
- reason: subject.profile === 'onboarding_human' ? 'onboarding' : 'session_human',
538
- reach: rule.reach,
539
- };
518
+ if (subject.profile === 'session_human') {
519
+ return { allowed: true, reason: 'session_human', reach: rule.reach };
540
520
  }
541
521
  if (rule.access === 'human_only') {
542
522
  return { allowed: false, reason: 'human_only', reach: rule.reach };
@@ -77,9 +77,9 @@ export interface ScopedDepsFactory {
77
77
  export declare const applyNetworkScopeToContext: (context: ResolvedToolContext, networkScopeId: string | null | undefined) => void;
78
78
  export { ONBOARDING_ALLOWED } from './mcp.authorization-policy.js';
79
79
  /**
80
- * Builds the onboarding gate message for MCP callers. Condensed from the
81
- * chat orchestrator's flow (chat.prompt.ts buildOnboarding) into a
82
- * 6-step tool-error guide suited for non-interactive MCP clients.
80
+ * Builds the onboarding gate message for REST Tool API callers. Condensed
81
+ * from the chat onboarding flow into a 6-step tool-error guide. MCP does
82
+ * not use this gate.
83
83
  */
84
84
  export declare function buildMcpOnboardingMessage(ctx: ResolvedToolContext): string;
85
85
  export declare const MCP_INSTRUCTIONS: string;