@agenticprimitives/fabric 0.0.0-alpha.1 → 0.0.0-alpha.4

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 (35) hide show
  1. package/dist/messaging/board.d.ts +84 -4
  2. package/dist/messaging/board.d.ts.map +1 -1
  3. package/dist/messaging/board.js +98 -7
  4. package/dist/messaging/board.js.map +1 -1
  5. package/dist/messaging/consult-routing.d.ts +289 -0
  6. package/dist/messaging/consult-routing.d.ts.map +1 -0
  7. package/dist/messaging/consult-routing.js +455 -0
  8. package/dist/messaging/consult-routing.js.map +1 -0
  9. package/dist/messaging/consult.d.ts +158 -0
  10. package/dist/messaging/consult.d.ts.map +1 -0
  11. package/dist/messaging/consult.js +141 -0
  12. package/dist/messaging/consult.js.map +1 -0
  13. package/dist/messaging/directory.d.ts +16 -0
  14. package/dist/messaging/directory.d.ts.map +1 -1
  15. package/dist/messaging/directory.js.map +1 -1
  16. package/dist/messaging/inbox-assistant.d.ts +68 -0
  17. package/dist/messaging/inbox-assistant.d.ts.map +1 -0
  18. package/dist/messaging/inbox-assistant.js +102 -0
  19. package/dist/messaging/inbox-assistant.js.map +1 -0
  20. package/dist/messaging/index.d.ts +6 -3
  21. package/dist/messaging/index.d.ts.map +1 -1
  22. package/dist/messaging/index.js +13 -2
  23. package/dist/messaging/index.js.map +1 -1
  24. package/dist/messaging/types.d.ts +22 -0
  25. package/dist/messaging/types.d.ts.map +1 -1
  26. package/dist/messaging/types.js +15 -1
  27. package/dist/messaging/types.js.map +1 -1
  28. package/dist/messaging/vault-store.d.ts +33 -0
  29. package/dist/messaging/vault-store.d.ts.map +1 -1
  30. package/dist/messaging/vault-store.js +53 -5
  31. package/dist/messaging/vault-store.js.map +1 -1
  32. package/dist/record-catalog.d.ts.map +1 -1
  33. package/dist/record-catalog.js +12 -0
  34. package/dist/record-catalog.js.map +1 -1
  35. package/package.json +6 -6
@@ -0,0 +1,455 @@
1
+ // Org-side member routing — pure substrate (spec 329 W2/W3; the org sibling of ./consult.ts).
2
+ // This module owns validated PURE decisions only: candidate ELIGIBILITY (roster ∩ topic
3
+ // participants ∩ consultable hint ∩ grant-present — consent is structural, never planner
4
+ // authority), the spec-281 filter→score→surface RANKING over public discovery facets (degrading
5
+ // fail-open to FEWER signals, never to more candidates), the depth-1 routing-tools guard, the
6
+ // consult-request builder (bounded context), and the turn-2 synthesis attribution/PROV shapes.
7
+ // Discovery I/O, DO custody, rate buckets, signing, and audit are the EXECUTION POINT's (demo-a2a).
8
+ import { CONSULT_QUESTION_MAX_CHARS, CONSULT_TAIL_CLIP, CONSULT_TAIL_MAX_ROWS, CONSULT_MEMBER_TIMEOUT_MS, consultGrantRecordKey, } from './consult.js';
9
+ import { channelParticipationPolicy } from './board.js';
10
+ /** Org-DO pending-consult ring key (spec 329 §4.1). */
11
+ export const routingPendingKey = (topicId, questionId) => `routing.pending:${topicId}:${questionId}`;
12
+ /** ConsultationIntent description-record key (spec 329 §5) — one per consulted member. */
13
+ export const consultationIntentKey = (questionId, memberSA) => `routing.consult:${questionId}:${memberSA.toLowerCase()}`;
14
+ /**
15
+ * roster ∩ topic participants ∩ consultable-hinted ∩ grant-present. Fail-closed on consent from
16
+ * BOTH directions (spec 329 §2.2): flag without grant ⇒ excluded; grant without flag ⇒ excluded.
17
+ * Restricted topics consult `canSeeChannel` participants only (a member is never asked about a
18
+ * conversation they cannot see); the org itself is never a candidate (org agents are not
19
+ * consultable — §4 loop prevention).
20
+ */
21
+ export function eligibleConsultMembers(args) {
22
+ const grants = new Set(args.grantMembers.map((m) => m.toLowerCase()));
23
+ const org = args.orgSA.toLowerCase();
24
+ const restricted = channelParticipationPolicy(args.channel) === 'restricted';
25
+ const participants = new Set((args.channel.members ?? []).map((m) => m.toLowerCase()));
26
+ const out = [];
27
+ const seen = new Set();
28
+ for (const row of args.roster) {
29
+ if (!row.current || row.consultable !== true)
30
+ continue;
31
+ const memberSA = (row.subject.match(/0x[0-9a-fA-F]{40}$/)?.[0] ?? '').toLowerCase();
32
+ if (!memberSA || memberSA === org || seen.has(memberSA))
33
+ continue;
34
+ if (!grants.has(memberSA))
35
+ continue; // hint without authority ⇒ not consultable (fail-closed)
36
+ if (restricted && !participants.has(memberSA))
37
+ continue; // §2.3 structural topic scope
38
+ seen.add(memberSA);
39
+ const orgRole = row.orgRole?.trim();
40
+ out.push({ memberSA, displayName: row.displayName || memberSA, ...(orgRole ? { orgRole } : {}) });
41
+ }
42
+ return out;
43
+ }
44
+ const W_FIT = 0.6;
45
+ const W_TRUST = 0.4;
46
+ /** Parse a comma-separated on-chain code list into a lowercased set. Empty/absent ⇒ empty set — an
47
+ * agent that has not published a facet is UNKNOWN, not universal (spec 331 §4.3). */
48
+ const codeSet = (v) => (v ?? '').split(',').map((s) => s.trim().toLowerCase()).filter(Boolean);
49
+ /** BCP-47: a member publishing `pt-br` satisfies a request for `pt`, never the reverse. Substring
50
+ * comparison is forbidden here — it makes `en` match `zh-Hant` via no meaningful relation, which is
51
+ * the class of accident this migration removes. */
52
+ const langMatches = (have, want) => have.some((h) => h === want || h.startsWith(`${want}-`));
53
+ /** Parse the spec-282 comma-joined `atl:skills` assertion into clean labels (bounded). */
54
+ function skillLabels(csv) {
55
+ if (!csv)
56
+ return [];
57
+ return csv.split(',').map((s) => s.trim()).filter(Boolean).slice(0, 32);
58
+ }
59
+ /**
60
+ * Structured fit (spec 331 §4.2), mirroring demo-discovery-a2a's `fitScore` term for term:
61
+ *
62
+ * 0.55 capabilityMatch · 0.15 specializationMatch · 0.10 regionMatch
63
+ * · 0.10 languageMatch · 0.10 focusMatch · 0.15 lexicalFallback (gated)
64
+ *
65
+ * WHY THE CATALOG IS NOT LOADED HERE. `need` resolution is an org-side act performed once per
66
+ * question against a catalog this package must not own — an advisory vocabulary is a downstream
67
+ * domain artifact. So the caller hands in `StructuredNeedV1` already resolved and DAG-expanded, and
68
+ * this function scores structure it is given. A caller that resolves nothing gets exactly the old
69
+ * lexical behaviour, which is why adopting this is not a flag day.
70
+ *
71
+ * Absence is never a penalty: a member who published no regions scores 0 on `regionMatch`, the same
72
+ * as one whose regions did not match. Not matching costs the boost, never the seat.
73
+ */
74
+ function fitOf(f, need, skillHints, cites, structured = {}) {
75
+ const declared = (f.capabilityIds ?? []).map((x) => x.toLowerCase());
76
+ const needed = (structured.capabilityIds ?? []).map((x) => x.toLowerCase());
77
+ let s = 0;
78
+ const exact = needed.filter((id) => declared.includes(id));
79
+ if (needed.length && exact.length) {
80
+ s += 0.55 * (exact.length / needed.length);
81
+ for (const id of exact)
82
+ cites.push(`declared ${id} (exact)`);
83
+ }
84
+ const specIds = (structured.specializationIds ?? []).map((x) => x.toLowerCase());
85
+ const specHits = declared.filter((id) => specIds.includes(id) && !exact.includes(id));
86
+ if (specHits.length) {
87
+ s += 0.15;
88
+ for (const id of specHits)
89
+ cites.push(`declared ${id}, specializes a requested capability`);
90
+ }
91
+ // Claimed-capability tier — declared AND independently endorsed beats a bare declaration. Only a
92
+ // capability the member DECLARED and that was ASKED FOR (`exact`) can be boosted; the endorsement's
93
+ // independence (self ignored, volume deduped, same-org discounted, staleness decayed) was settled by the
94
+ // transport, so `endorsedCapabilityIds` is already trustworthy. Capped HARD (+0.05 each, ≤0.10 total):
95
+ // endorsement corroborates a declared capability, never manufactures one — a gameable boost is worse than
96
+ // none (the explicit bar), and the cap also contains any same-org collusion the transport could not see.
97
+ const endorsed = new Set((f.endorsedCapabilityIds ?? []).map((x) => x.toLowerCase()));
98
+ const endorsedHits = exact.filter((id) => endorsed.has(id));
99
+ if (endorsedHits.length) {
100
+ s += Math.min(0.10, 0.05 * endorsedHits.length);
101
+ for (const id of endorsedHits)
102
+ cites.push(`declared ${id} AND independently endorsed (claimed tier)`);
103
+ }
104
+ const regions = codeSet(f.regions);
105
+ const wantRegions = (structured.regions ?? []).map((r) => r.toLowerCase());
106
+ const matchedRegions = [...new Set(wantRegions.filter((r) => regions.includes(r)))];
107
+ if (wantRegions.length && matchedRegions.length) {
108
+ s += 0.10 * Math.min(1, matchedRegions.length / wantRegions.length);
109
+ cites.push(`covers ${matchedRegions.map((r) => r.toUpperCase()).join(', ')} (requested)`);
110
+ }
111
+ const langs = codeSet(f.languages);
112
+ const wantLangs = (structured.languages ?? []).map((l) => l.toLowerCase());
113
+ const matchedLangs = wantLangs.filter((l) => langMatches(langs, l));
114
+ if (wantLangs.length && matchedLangs.length) {
115
+ s += 0.10 * Math.min(1, matchedLangs.length / wantLangs.length);
116
+ cites.push(`speaks ${matchedLangs.join(', ')} (requested)`);
117
+ }
118
+ const focus = codeSet(f.focusAreas);
119
+ const matchedFocus = (structured.focusAreas ?? []).map((x) => x.toLowerCase())
120
+ .filter((x) => focus.some((y) => y.includes(x) || x.includes(y)));
121
+ if (matchedFocus.length) {
122
+ s += Math.min(0.10, 0.05 * matchedFocus.length);
123
+ cites.push(`focus: ${matchedFocus.join(', ')}`);
124
+ }
125
+ // Hack #3 demoted, not deleted. Fires ONLY when the caller resolved no capability id, and says so
126
+ // in the evidence — so a result carried by a substring coincidence is inspectable rather than
127
+ // indistinguishable from a structured one (ADR-0013).
128
+ const lexicalOnly = needed.length === 0;
129
+ if (lexicalOnly) {
130
+ const hay = [f.name, f.displayName, f.description, f.skills].filter(Boolean).join(' ').toLowerCase();
131
+ const wanted = need.trim().toLowerCase();
132
+ let lex = 0;
133
+ if (!wanted)
134
+ lex = 0.15;
135
+ else {
136
+ const toks = wanted.split(/\s+/).filter((t) => t.length > 2);
137
+ const hits = toks.filter((t) => hay.includes(t)).length;
138
+ lex = toks.length ? hits / toks.length : 0.15;
139
+ }
140
+ for (const sk of skillHints)
141
+ if (hay.includes(sk.toLowerCase()))
142
+ lex = Math.min(1, lex + 0.2);
143
+ if (lex > 0) {
144
+ s += 0.15 * lex;
145
+ cites.push('— no capability id resolved from the question; lexical fallback only');
146
+ }
147
+ }
148
+ return {
149
+ score: Math.min(s, 1),
150
+ capabilityHits: exact.length + specHits.length,
151
+ regionHits: matchedRegions.length,
152
+ lexicalOnly,
153
+ endorsedCapabilityIds: endorsedHits,
154
+ };
155
+ }
156
+ function trustOf(f, cites) {
157
+ let s = 0;
158
+ if (f.registered) {
159
+ s += 0.5;
160
+ cites.push('active registry entry');
161
+ }
162
+ if (f.shaclConforms) {
163
+ s += 0.2;
164
+ cites.push('SHACL-conformant');
165
+ }
166
+ const n = f.facets?.length ?? 0;
167
+ s += Math.min(n, 5) * 0.06;
168
+ if (n)
169
+ cites.push(`${n} on-chain facet(s)`);
170
+ // Claimed-capability tier corroboration — DISTINCT non-self endorsers (self & volume already excluded).
171
+ // Capped below registration and saturating fast: an endorsement is cheap, so it corroborates, never
172
+ // authorises (ADR-0040), and undetected same-org collusion is contained by the cap.
173
+ const e = f.independentEndorsers ?? 0;
174
+ if (e > 0) {
175
+ s += Math.min(0.10, 0.05 * e);
176
+ cites.push(`${e} independent endorser(s)`);
177
+ }
178
+ return Math.min(s, 1);
179
+ }
180
+ /**
181
+ * Rank the ELIGIBLE set (spec 281 verbatim: mandates filter, `0.6·fit + 0.4·trust` scores,
182
+ * top-`max` surfaced with evidence). `facets === null` ⇒ discovery unreachable ⇒ degraded mode:
183
+ * the eligible set passes through un-ranked with `enriched:false`. A candidate discovery does not
184
+ * know keeps its consent-derived seat (fewer signals, never fewer rights) but ranks below enriched
185
+ * peers and is exempt from skill mandates it cannot prove or disprove — eligibility (consent) was
186
+ * already settled structurally.
187
+ */
188
+ export function rankConsultCandidates(args) {
189
+ const max = Math.max(1, args.max ?? args.eligible.length);
190
+ if (!args.facets) {
191
+ return {
192
+ enriched: false,
193
+ droppedByMandates: 0,
194
+ candidates: args.eligible.slice(0, max).map((m) => ({
195
+ ...m, skills: [], score: 0, enriched: false, satisfiedMandates: [],
196
+ evidence: ['discovery unreachable — eligibility (consent) only, roster order'],
197
+ })),
198
+ };
199
+ }
200
+ const hints = args.skillHints ?? [];
201
+ let dropped = 0;
202
+ const scored = [];
203
+ for (const m of args.eligible) {
204
+ const f = args.facets[m.memberSA];
205
+ if (!f) {
206
+ scored.push({ ...m, skills: [], score: 0, enriched: false, satisfiedMandates: [], evidence: ['not in discovery — roster signals only'] });
207
+ continue;
208
+ }
209
+ // Person agents only (spec 329 §4): an org-kind candidate is dropped, mandate-style.
210
+ if (f.kind && /org/i.test(f.kind)) {
211
+ dropped++;
212
+ continue;
213
+ }
214
+ const satisfied = [];
215
+ let failedMandate = false;
216
+ for (const hint of hints) {
217
+ const hay = [f.skills, f.description, f.displayName, f.name].filter(Boolean).join(' ').toLowerCase();
218
+ if (!hay.includes(hint.toLowerCase())) {
219
+ failedMandate = true;
220
+ break;
221
+ }
222
+ satisfied.push(`skill:${hint}`);
223
+ }
224
+ if (failedMandate) {
225
+ dropped++;
226
+ continue;
227
+ }
228
+ const cites = [];
229
+ const fit = fitOf(f, args.need, hints, cites, args.structured ?? {});
230
+ const trust = trustOf(f, cites);
231
+ const score = Math.round(Math.min(W_FIT * fit.score + W_TRUST * trust, 1) * 100) / 100;
232
+ scored.push({
233
+ ...m,
234
+ ...(f.name ? { handle: f.name } : {}),
235
+ skills: skillLabels(f.skills),
236
+ capabilityIds: f.capabilityIds ?? [],
237
+ capabilityHits: fit.capabilityHits, regionHits: fit.regionHits, lexicalOnly: fit.lexicalOnly,
238
+ endorsedCapabilityIds: fit.endorsedCapabilityIds,
239
+ score, enriched: true, satisfiedMandates: satisfied, evidence: cites,
240
+ });
241
+ }
242
+ // DETERMINISTIC ordering — ties break on STRUCTURE, never on array order. Region participates as a
243
+ // tie-break only: it can reorder candidates but can never eliminate one, which is the whole
244
+ // difference between this and the `mandates.geo` substring hard-filter it replaces.
245
+ scored.sort((a, b) => b.score - a.score
246
+ || (b.capabilityHits ?? 0) - (a.capabilityHits ?? 0)
247
+ || (b.regionHits ?? 0) - (a.regionHits ?? 0)
248
+ || Number(a.lexicalOnly ?? false) - Number(b.lexicalOnly ?? false)
249
+ || a.displayName.localeCompare(b.displayName));
250
+ return { enriched: true, droppedByMandates: dropped, candidates: scored.slice(0, max) };
251
+ }
252
+ // ── Depth-1 guard (spec 329 §4 loop prevention) ────────────────────────────────────────────────
253
+ /**
254
+ * May THIS trigger offer the routing tools (find_members / ask_member)? False unless the topic's
255
+ * routing flag AND assistant are on, the org consult wire is custodied, and the triggering post is
256
+ * HUMAN-authored — an actor-marked (agent-authored) post can NEVER re-trigger routing, which with
257
+ * the consult handler's empty routing toolset makes consults depth-1 by construction.
258
+ */
259
+ export function routingToolsAllowed(args) {
260
+ if (!args.routing || !args.assistant)
261
+ return false;
262
+ if (!args.wirePresent)
263
+ return false;
264
+ if (args.triggerActor)
265
+ return false; // depth-1: agent-authored triggers never route
266
+ return true;
267
+ }
268
+ /** The degrade verdict for a finished (or thrown) ROUTED turn. Fail-closed toward the member:
269
+ * every branch ends with a posted reply. */
270
+ export function routedTurnDegrade(s) {
271
+ if (s.posted) {
272
+ return s.outcome === 'completed'
273
+ ? { action: 'none' }
274
+ : { action: 'none', cause: `reply posted; routed residue failed: ${s.error ?? 'unknown error'}` };
275
+ }
276
+ const cause = s.outcome === 'completed'
277
+ ? 'routed plan completed without post_topic_message (read-only plan)'
278
+ : `routed turn failed: ${s.error ?? 'unknown error'}`;
279
+ return s.askedCount > 0 ? { action: 'post-status', cause } : { action: 'plain-turn', cause };
280
+ }
281
+ // ── Consult request builder (bounded context — spec 329 §2.3) ──────────────────────────────────
282
+ /** Build the ConsultRequestV1 the org puts on the task rail, clipping question + tail to the
283
+ * member-side parse bounds so what is sent IS what the member's gate accepts. */
284
+ export function buildConsultRequest(args) {
285
+ const tail = (args.tail ?? [])
286
+ .filter((r) => r.bodyText.trim())
287
+ .slice(-CONSULT_TAIL_MAX_ROWS)
288
+ .map((r) => ({ author: r.author.slice(0, 120) || 'member', bodyText: r.bodyText.slice(0, CONSULT_TAIL_CLIP) }));
289
+ const topicTitle = args.topicTitle?.trim() ? args.topicTitle.trim().slice(0, 200) : undefined;
290
+ return {
291
+ goal: args.question.trim().slice(0, CONSULT_QUESTION_MAX_CHARS),
292
+ context: {
293
+ orgSA: args.orgSA.toLowerCase(),
294
+ topicId: args.topicId,
295
+ questionId: args.questionId,
296
+ ...(topicTitle ? { topicTitle } : {}),
297
+ ...(tail.length ? { topicTail: tail } : {}),
298
+ },
299
+ };
300
+ }
301
+ /** Build the drafted→expressed ConsultationIntent description record (spec 329 §5). */
302
+ export function buildConsultationIntentRecord(args) {
303
+ return {
304
+ version: 'ap.consultation-intent.v1',
305
+ id: `${args.questionId}:${args.memberSA.toLowerCase()}`,
306
+ direction: 'receive',
307
+ object: '',
308
+ expressedBy: args.orgSA,
309
+ addressedTo: [args.memberSA],
310
+ constraints: { timeoutMs: args.timeoutMs ?? CONSULT_MEMBER_TIMEOUT_MS, topicId: args.topicId },
311
+ status: 'expressed',
312
+ createdAt: args.now ?? new Date().toISOString(),
313
+ };
314
+ }
315
+ /** Deterministic attribution buckets — the synthesis post + audit derive from THIS, never from
316
+ * planner output (the LLM words the reply; the harness owns who-said-what). */
317
+ export function consultAttribution(outcomes) {
318
+ const names = (s) => outcomes.filter((o) => o.status === s).map((o) => o.displayName);
319
+ return {
320
+ consulted: outcomes.map((o) => o.displayName),
321
+ contributed: names('answered'),
322
+ declined: names('declined'),
323
+ timedOut: names('timedOut'),
324
+ failed: names('failed'),
325
+ revoked: names('revoked'),
326
+ };
327
+ }
328
+ /** PROV fields for the synthesis post (spec 329 §6): every consulted agent, derived-from ONLY the
329
+ * contributing answers' ConsultationIntent record ids. */
330
+ export function buildConsultProvenance(questionId, outcomes) {
331
+ return {
332
+ consultedAgent: outcomes.map((o) => o.memberSA),
333
+ wasDerivedFrom: outcomes
334
+ .filter((o) => o.status === 'answered')
335
+ .map((o) => consultationIntentKey(questionId, o.memberSA)),
336
+ };
337
+ }
338
+ /** The harness-read context block the synthesis goal embeds (answers quoted WITH names — the
339
+ * approved quoting decision; non-answers stated plainly so the model can attribute honestly). */
340
+ export function synthesisOutcomeLines(outcomes) {
341
+ const lines = outcomes.map((o) => {
342
+ switch (o.status) {
343
+ case 'answered':
344
+ return `- ${o.displayName}'s agent answered: "${(o.answer?.answer ?? '').slice(0, 1200)}"`;
345
+ case 'declined':
346
+ return `- ${o.displayName}'s agent declined${o.answer?.declineReason ? ` (${o.answer.declineReason.slice(0, 200)})` : ''}.`;
347
+ case 'timedOut':
348
+ return `- ${o.displayName}'s agent didn't respond in time.`;
349
+ case 'revoked':
350
+ return `- ${o.displayName} withdrew their consult opt-in before the reply — their answer was discarded.`;
351
+ default:
352
+ return `- ${o.displayName}'s agent could not be reached.`;
353
+ }
354
+ });
355
+ return lines.join('\n');
356
+ }
357
+ /** The deterministic (rule-based) synthesis body — exact attribution, no model required. */
358
+ export function deterministicSynthesisBody(question, outcomes) {
359
+ const a = consultAttribution(outcomes);
360
+ const head = `I asked ${a.consulted.length} member agent${a.consulted.length === 1 ? '' : 's'} (${a.consulted.join(', ')}) about: "${question.slice(0, 200)}".`;
361
+ const answers = outcomes
362
+ .filter((o) => o.status === 'answered')
363
+ .map((o) => `${o.displayName}'s agent: "${(o.answer?.answer ?? '').slice(0, 600)}"`);
364
+ const misses = [];
365
+ if (a.declined.length)
366
+ misses.push(`${a.declined.join(', ')} declined`);
367
+ if (a.timedOut.length)
368
+ misses.push(`${a.timedOut.join(', ')} didn't respond in time`);
369
+ if (a.failed.length)
370
+ misses.push(`${a.failed.join(', ')} could not be reached`);
371
+ if (a.revoked.length)
372
+ misses.push(`${a.revoked.join(', ')} withdrew their opt-in (answer discarded)`);
373
+ return [head, ...answers, misses.length ? `(${misses.join('; ')}.)` : '']
374
+ .filter(Boolean)
375
+ .join('\n\n');
376
+ }
377
+ /** The one-phrase SELECTION BASIS for a candidate (spec 329 §4 skill-based auto-selection):
378
+ * the turn-1 status post and the goal's candidate lines both state WHY a member is (or may be)
379
+ * consulted — published capabilities when they exist, and the honest lesser basis when they don't.
380
+ * Prose says CAPABILITY (capability-architecture.md §1); the `skills` field name is the legacy
381
+ * `atl:skills` projection key and is immutable. */
382
+ export function consultSelectionBasis(c, matchedRole = false) {
383
+ // Claimed-capability tier — when a member is DECLARED AND independently ENDORSED for a requested
384
+ // capability, the basis says so: a declaration corroborated by a third party is a stronger reason to
385
+ // pick them than a bare self-declaration, and the copy must not hide the difference (capability-
386
+ // architecture.md §2 — three assertion strengths, presented distinctly).
387
+ const endorsed = (c.endorsedCapabilityIds ?? []).map(humanizeCapability);
388
+ const endorseClause = endorsed.length ? ` — declared AND endorsed for ${endorsed.join(', ')}` : '';
389
+ // spec 329 §12 — a ROLE match outranks a generic skill match, so when the role drove the pick the
390
+ // basis SAYS the role (and only the role). Never claimed without an asserted role.
391
+ if (matchedRole && c.orgRole?.trim())
392
+ return `org role: ${c.orgRole.trim()}${endorseClause}`;
393
+ // Humanized: this string is quoted verbatim into a member-facing discussion post, so it must read
394
+ // as English rather than as a CURIE list. The identity is unchanged — only its rendering.
395
+ if (c.skills.length)
396
+ return `published capabilities: ${c.skills.map(humanizeCapability).join(', ')}${endorseClause}`;
397
+ return c.enriched
398
+ ? 'no published capabilities — matched on name/description'
399
+ : 'no capability data readable — consent-based eligibility only';
400
+ }
401
+ /** One compact goal line per candidate — published skills FIRST (the model matches the question's
402
+ * subject against these), an EXPLICIT no-skills marker (never hallucinated expertise), then the
403
+ * ranking-evidence hint. */
404
+ /**
405
+ * Render a published capability for a HUMAN: `adv:succession-plan-design` → "succession plan
406
+ * design". Presentation only — the id string is the identity and is never rewritten (ADR-0051's
407
+ * prose/key split: the prose says "capability", the key stays exactly as published).
408
+ *
409
+ * This is a pure transform on the CURIE, deliberately NOT a catalog lookup: the catalog is a
410
+ * downstream domain artifact and this package must not depend on one. A canonical prefLabel would
411
+ * read slightly better; a substrate dependency on an advisory vocabulary would cost much more than
412
+ * that is worth. A token that is not CURIE-shaped (a legacy free-text label) passes through
413
+ * untouched.
414
+ */
415
+ export function humanizeCapability(id) {
416
+ const local = /^[a-z][a-z0-9]*:([a-z0-9][a-z0-9-]*)$/i.exec(id.trim())?.[1];
417
+ return local ? local.replace(/-/g, ' ') : id.trim();
418
+ }
419
+ export function consultCandidateLine(c) {
420
+ const who = c.handle ? `${c.displayName} (${c.handle})` : c.displayName;
421
+ // spec 329 §12 — the org role leads when asserted: it is the stronger, member-signed signal and
422
+ // the model is instructed to prefer it over a generic skill match.
423
+ const role = c.orgRole?.trim() ? `role: ${c.orgRole.trim()} — ` : '';
424
+ const skills = c.skills.length
425
+ ? `published capabilities: [${c.skills.map(humanizeCapability).join(', ')}]`
426
+ : c.enriched
427
+ ? 'NO published capabilities (match only on displayName/description, and say that basis if you consult them)'
428
+ : 'NO capability data (discovery unreachable — consent-based eligibility only)';
429
+ const ev = c.evidence.length ? ` — ${c.evidence.slice(0, 3).join('; ')}` : '';
430
+ return `- ${who} — memberSA ${c.memberSA} — ${role}${skills}${ev}`;
431
+ }
432
+ /**
433
+ * Does the question ADDRESS this candidate's org role (spec 329 §12)? Pure, deterministic, and
434
+ * conservative: a normalized substring match of the asserted role phrase in the question
435
+ * ("@ask tax advisor …", "ask our tax advisor about …" both hit "tax advisor"). Used by the
436
+ * DETERMINISTIC (no-LLM) routed turn to state an honest basis; the LLM turn does its own matching
437
+ * under ROUTING_CONTRACT. No role asserted ⇒ false (a role is never inferred from skills).
438
+ */
439
+ export function questionAddressesRole(question, orgRole) {
440
+ const role = orgRole?.trim().toLowerCase().replace(/\s+/g, ' ');
441
+ if (!role)
442
+ return false;
443
+ return question.toLowerCase().replace(/\s+/g, ' ').includes(role);
444
+ }
445
+ /** The deterministic turn-1 status body — the honest "asking N members" post (spec 329 §4.1).
446
+ * Entries may carry a selection `basis` (see consultSelectionBasis), rendered in parentheses:
447
+ * "Asking 1 member's agent (alice (published skills: water systems)) — …". Plain strings keep
448
+ * the pre-329-§4 shape. */
449
+ export function deterministicStatusBody(members) {
450
+ const names = members.map((m) => (typeof m === 'string' ? m : m.basis ? `${m.displayName} (${m.basis})` : m.displayName));
451
+ return `Asking ${names.length} member${names.length === 1 ? '' : 's'}' agent${names.length === 1 ? '' : 's'} (${names.join(', ')}) — I'll follow up here with what they say.`;
452
+ }
453
+ /** Re-export the grant-store key so execution points scanning eligibility import ONE name. */
454
+ export { consultGrantRecordKey };
455
+ //# sourceMappingURL=consult-routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consult-routing.js","sourceRoot":"","sources":["../../src/messaging/consult-routing.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,wFAAwF;AACxF,yFAAyF;AACzF,gGAAgG;AAChG,8FAA8F;AAC9F,+FAA+F;AAC/F,oGAAoG;AACpG,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GAKtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,0BAA0B,EAAkB,MAAM,YAAY,CAAC;AAExE,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAU,EAAE,CAC/E,mBAAmB,OAAO,IAAI,UAAU,EAAE,CAAC;AAE7C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,UAAkB,EAAE,QAAgB,EAAU,EAAE,CACpF,mBAAmB,UAAU,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;AA0B5D;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAOtC;IACC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,YAAY,CAAC;IAC7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACvF,MAAM,GAAG,GAA8B,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI;YAAE,SAAS;QACvD,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpF,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QAClE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,yDAAyD;QAC9F,IAAI,UAAU,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,8BAA8B;QACvF,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAqFD,MAAM,KAAK,GAAG,GAAG,CAAC;AAClB,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;sFACsF;AACtF,MAAM,OAAO,GAAG,CAAC,CAA4B,EAAY,EAAE,CACzD,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE1E;;oDAEoD;AACpD,MAAM,WAAW,GAAG,CAAC,IAAc,EAAE,IAAY,EAAE,EAAE,CACnD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AAE3D,0FAA0F;AAC1F,SAAS,WAAW,CAAC,GAA8B;IACjD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC;AAoBD;;;;;;;;;;;;;;GAcG;AACH,SAAS,KAAK,CACZ,CAA2B,EAAE,IAAY,EAAE,UAAoB,EAAE,KAAe,EAChF,aAA+B,EAAE;IAEjC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM,EAAE,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC,IAAI,IAAI,CAAC;QACV,KAAK,MAAM,EAAE,IAAI,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,sCAAsC,CAAC,CAAC;IAC9F,CAAC;IAED,iGAAiG;IACjG,oGAAoG;IACpG,yGAAyG;IACzG,uGAAuG;IACvG,0GAA0G;IAC1G,yGAAyG;IACzG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,KAAK,MAAM,EAAE,IAAI,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,4CAA4C,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3E,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,IAAI,WAAW,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;QAChD,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,UAAU,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,CAAC,UAAU,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,SAAS,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QAC5C,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,YAAY,GAAG,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC3E,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,kGAAkG;IAClG,8FAA8F;IAC9F,sDAAsD;IACtD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IACxC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACrG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM;YAAE,GAAG,GAAG,IAAI,CAAC;aACnB,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAChD,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,UAAU;YAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;gBAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QAC9F,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACZ,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM;QAC9C,UAAU,EAAE,cAAc,CAAC,MAAM;QACjC,WAAW;QACX,qBAAqB,EAAE,YAAY;KACpC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,CAA2B,EAAE,KAAe;IAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAAC,CAAC,IAAI,GAAG,CAAC;QAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAAC,CAAC;IACpE,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;QAAC,CAAC,IAAI,GAAG,CAAC;QAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAAC,CAAC;IAClE,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;IAChC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC5C,wGAAwG;IACxG,oGAAoG;IACpG,oFAAoF;IACpF,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAAC,CAAC;IACzF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAUrC;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,iBAAiB,EAAE,CAAC;YACpB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClD,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE;gBAClE,QAAQ,EAAE,CAAC,kEAAkE,CAAC;aAC/E,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,wCAAwC,CAAC,EAAE,CAAC,CAAC;YAC1I,SAAS;QACX,CAAC;QACD,qFAAqF;QACrF,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAC3D,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YACrG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAAC,aAAa,GAAG,IAAI,CAAC;gBAAC,MAAM;YAAC,CAAC;YACvE,SAAS,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,aAAa,EAAE,CAAC;YAAC,OAAO,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,CAAC;YACJ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;YAC7B,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,EAAE;YACpC,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5F,qBAAqB,EAAE,GAAG,CAAC,qBAAqB;YAChD,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK;SACrE,CAAC,CAAC;IACL,CAAC;IACD,mGAAmG;IACnG,4FAA4F;IAC5F,oFAAoF;IACpF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;WAClC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC;WACjD,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;WACzC,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;WAC/D,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACjD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,kGAAkG;AAElG;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAKnC;IACC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,CAAC,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC,CAAC,+CAA+C;IACpF,OAAO,IAAI,CAAC;AACd,CAAC;AAiCD;6CAC6C;AAC7C,MAAM,UAAU,iBAAiB,CAAC,CAAoB;IACpD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,CAAC,CAAC,OAAO,KAAK,WAAW;YAC9B,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;YACpB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,wCAAwC,CAAC,CAAC,KAAK,IAAI,eAAe,EAAE,EAAE,CAAC;IACtG,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,WAAW;QACrC,CAAC,CAAC,mEAAmE;QACrE,CAAC,CAAC,uBAAuB,CAAC,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC;IACxD,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAC/F,CAAC;AAED,kGAAkG;AAElG;kFACkF;AAClF,MAAM,UAAU,mBAAmB,CAAC,IAOnC;IACC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SAChC,KAAK,CAAC,CAAC,qBAAqB,CAAC;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;IAClH,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAC;QAC/D,OAAO,EAAE;YACP,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5C;KACF,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,6BAA6B,CAAC,IAO7C;IACC,OAAO;QACL,OAAO,EAAE,2BAA2B;QACpC,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE;QACvD,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,IAAI,CAAC,KAA4C;QAC9D,WAAW,EAAE,CAAC,IAAI,CAAC,QAAkD,CAAC;QACtE,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,yBAAyB,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;QAC9F,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAChD,CAAC;AACJ,CAAC;AA2BD;gFACgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,QAA4B;IAC7D,MAAM,KAAK,GAAG,CAAC,CAAuB,EAAY,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACtH,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QAC7C,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC;QAC9B,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC;QAC3B,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC;QAC3B,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;QACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;2DAC2D;AAC3D,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,QAA4B;IACrF,OAAO;QACL,cAAc,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC/C,cAAc,EAAE,QAAQ;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;kGACkG;AAClG,MAAM,UAAU,qBAAqB,CAAC,QAA4B;IAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,UAAU;gBACb,OAAO,KAAK,CAAC,CAAC,WAAW,uBAAuB,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC;YAC7F,KAAK,UAAU;gBACb,OAAO,KAAK,CAAC,CAAC,WAAW,oBAAoB,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;YAC9H,KAAK,UAAU;gBACb,OAAO,KAAK,CAAC,CAAC,WAAW,kCAAkC,CAAC;YAC9D,KAAK,SAAS;gBACZ,OAAO,KAAK,CAAC,CAAC,WAAW,+EAA+E,CAAC;YAC3G;gBACE,OAAO,KAAK,CAAC,CAAC,WAAW,gCAAgC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,QAA4B;IACvF,MAAM,CAAC,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,SAAS,CAAC,MAAM,gBAAgB,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC;IAChK,MAAM,OAAO,GAAG,QAAQ;SACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACvF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACtF,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAChF,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACtG,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;SACtE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED;;;;oDAIoD;AACpD,MAAM,UAAU,qBAAqB,CACnC,CAAwF,EACxF,WAAW,GAAG,KAAK;IAEnB,iGAAiG;IACjG,qGAAqG;IACrG,iGAAiG;IACjG,yEAAyE;IACzE,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACzE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,gCAAgC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnG,kGAAkG;IAClG,mFAAmF;IACnF,IAAI,WAAW,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE;QAAE,OAAO,aAAa,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;IAC7F,kGAAkG;IAClG,0FAA0F;IAC1F,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;IACrH,OAAO,CAAC,CAAC,QAAQ;QACf,CAAC,CAAC,yDAAyD;QAC3D,CAAC,CAAC,8DAA8D,CAAC;AACrE,CAAC;AAED;;6BAE6B;AAC7B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC3C,MAAM,KAAK,GAAG,wCAAwC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAqB;IACxD,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IACxE,gGAAgG;IAChG,mEAAmE;IACnE,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM;QAC5B,CAAC,CAAC,4BAA4B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC5E,CAAC,CAAC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,2GAA2G;YAC7G,CAAC,CAAC,6EAA6E,CAAC;IACpF,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,OAAO,KAAK,GAAG,eAAe,CAAC,CAAC,QAAQ,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,EAAE,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,OAA2B;IACjF,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpE,CAAC;AAED;;;4BAG4B;AAC5B,MAAM,UAAU,uBAAuB,CAAC,OAAgE;IACtG,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1H,OAAO,UAAU,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC;AAChL,CAAC;AAED,8FAA8F;AAC9F,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1,158 @@
1
+ import type { CanonicalAgentId } from '@agenticprimitives/types';
2
+ import type { ContextRefV1 } from './types.js';
3
+ /** The consult A2A skill id — the delegation's `allowedMethods` selector derives from THIS string
4
+ * (`skillSelector('discussion.consult')`, spec 269 FR-4.2). Never `A2A_ANY_SKILL`. */
5
+ export declare const CONSULT_SKILL_ID: "discussion.consult";
6
+ /** Member-side per-org fixed window (spec 329 §3.2): 12 consults / hour / org. Exceeding ⇒ the
7
+ * task fails typed + audited (`a2a.consult.rateLimited`); decided with `fixedWindowAllow`. */
8
+ export declare const CONSULT_RATE_WINDOW_MS: number;
9
+ export declare const CONSULT_RATE_MAX = 12;
10
+ /** Default consultability-delegation lifetime (spec 329 §2.1) — re-opt-in refreshes. */
11
+ export declare const CONSULT_GRANT_VALIDITY_SECONDS: number;
12
+ /** Fan-out per routed question: default 3, steward-tunable 1..5. */
13
+ export declare const ROUTING_FANOUT_DEFAULT = 3;
14
+ export declare const ROUTING_FANOUT_MIN = 1;
15
+ export declare const ROUTING_FANOUT_MAX = 5;
16
+ /** Per-topic routing bucket (on top of 327's dispatch bucket): 3 routed questions / 10 min. */
17
+ export declare const ROUTING_RATE_WINDOW_MS: number;
18
+ export declare const ROUTING_RATE_MAX = 3;
19
+ /** Per-member consult timeout (spec 329 §4): a member agent that hasn't completed by then is
20
+ * reported as timed out in the synthesis attribution. */
21
+ export declare const CONSULT_MEMBER_TIMEOUT_MS = 60000;
22
+ /** PROV-O provenance carried by the turn-2 synthesis post (spec 329 §6): `apmsg:consultedAgent`
23
+ * (every agent consulted for this reply) + `prov:wasDerivedFrom` (the ConsultationIntent record
24
+ * ids whose answers CONTRIBUTED). House rule: reuse PROV directly, no parallel terms. */
25
+ export interface ConsultProvenanceV1 {
26
+ consultedAgent: string[];
27
+ wasDerivedFrom: string[];
28
+ }
29
+ /** contextRef kind carried by the turn-1 status post + turn-2 synthesis (spec 329 §6;
30
+ * cbox/interaction-vocabulary.ttl `apmsg:routedConsultation`). */
31
+ export declare const ROUTED_CONSULTATION_CONTEXT_KIND: "routed-consultation";
32
+ /** The org-vault record name family holding member consultability grants (spec 329 §2.1) —
33
+ * exported so W2's `find_members` eligibility read and the opt-in ceremony key identically. */
34
+ export declare const consultGrantRecordKey: (memberSA: string) => string;
35
+ /** Build the routed-consultation contextRef: id = `<orgSA>/<topicId>/<questionId>` (spec 329 §6). */
36
+ export declare function routedConsultationContextRef(orgSA: string, topicId: string, questionId: string): ContextRefV1;
37
+ /** One clipped topic-tail row carried with a routed question (spec 329 §2.3). */
38
+ export interface ConsultTailRowV1 {
39
+ author: string;
40
+ bodyText: string;
41
+ }
42
+ /** Bounds on the carried context — the consult turn is small by construction. */
43
+ export declare const CONSULT_QUESTION_MAX_CHARS = 2000;
44
+ export declare const CONSULT_TAIL_MAX_ROWS = 8;
45
+ export declare const CONSULT_TAIL_CLIP = 300;
46
+ /**
47
+ * The consult task payload (spec 329 §5 EXECUTION framing): an orchestration Intent
48
+ * `{ goal, context }` — the goal IS the question; the context pins the org, topic, and
49
+ * question id. This is the ONLY executing intent machinery in spec 329.
50
+ */
51
+ export interface ConsultRequestV1 {
52
+ /** The question text (the orchestration Intent's goal). */
53
+ goal: string;
54
+ context: {
55
+ /** The consulting org SA (0x, lowercased on parse). */
56
+ orgSA: string;
57
+ /** The triggering topic (`conv_*`). */
58
+ topicId: string;
59
+ /** The org-side routing id — `routing.pending` / ConsultationIntent records key on it. */
60
+ questionId: string;
61
+ topicTitle?: string;
62
+ /** Clipped topic tail (≤ CONSULT_TAIL_MAX_ROWS rows, bodies ≤ CONSULT_TAIL_CLIP chars). */
63
+ topicTail?: ConsultTailRowV1[];
64
+ };
65
+ }
66
+ export type ConsultParseResult = {
67
+ ok: true;
68
+ request: ConsultRequestV1;
69
+ } | {
70
+ ok: false;
71
+ error: string;
72
+ };
73
+ /** Parse + bound an inbound consult payload, fail-closed. Unknown/oversized context is CLIPPED
74
+ * (data, never authority — ADR-0041); a missing goal/org/topic/question id REJECTS. */
75
+ export declare function parseConsultRequest(input: unknown): ConsultParseResult;
76
+ /**
77
+ * The member agent's structured answer artifact (spec 329 §3.2/§6). Wire tag
78
+ * `ap.consult-answer.v1` ↔ apmsg:ConsultAnswer (tbox/messaging.ttl); validated by
79
+ * apmsg:ConsultAnswerShape's TS mirror below: exactly one actor, answered XOR declined.
80
+ * Rides the a2a task Artifact (the runtime binds apful:bodyHash over this body).
81
+ */
82
+ export interface ConsultAnswerV1 {
83
+ version: 'ap.consult-answer.v1';
84
+ /** The org-side routing correlation id (from the request context). */
85
+ questionId: string;
86
+ /** The consulting org SA (0x, lowercased). */
87
+ orgSA: string;
88
+ topicId: string;
89
+ /** The question answered (echo, clipped — synthesis renders it without re-reading the task). */
90
+ question: string;
91
+ /** Present iff answered (xor `declined`). */
92
+ answer?: string;
93
+ /** Present (true) iff the member's agent explicitly declined (xor `answer`). */
94
+ declined?: true;
95
+ /** Optional free-text decline reason. */
96
+ declineReason?: string;
97
+ /** spec 324 §9 acting-agent provenance — ALWAYS the member SA (pinned by the builder). */
98
+ actor: CanonicalAgentId;
99
+ respondedAt: string;
100
+ }
101
+ export type ConsultAnswerBuildResult = {
102
+ ok: true;
103
+ answer: ConsultAnswerV1;
104
+ } | {
105
+ ok: false;
106
+ error: string;
107
+ };
108
+ /** Max answer/decline-reason length carried back to the org. */
109
+ export declare const CONSULT_ANSWER_MAX_CHARS = 4000;
110
+ /**
111
+ * Build the ConsultAnswer artifact body (spec 329 §3.2). IDENTITY-PINNED by construction: the
112
+ * caller supplies only the outcome — `actor` is ALWAYS the member principal, and the request
113
+ * correlation (org/topic/question) comes from the PARSED request, never planner output.
114
+ * Enforces answered XOR declined, fail-closed (ADR-0013): an empty answer without an explicit
115
+ * decline is an error, never a silent empty artifact.
116
+ */
117
+ export declare function buildConsultAnswer(request: ConsultRequestV1, opts: {
118
+ member: CanonicalAgentId;
119
+ answer?: string;
120
+ declined?: boolean;
121
+ declineReason?: string;
122
+ now?: string;
123
+ }): ConsultAnswerBuildResult;
124
+ export type ConsultAnswerValidationError = 'bad_version' | 'missing_question_id' | 'missing_org' | 'missing_topic' | 'missing_actor' | 'answered_and_declined' | 'neither_answered_nor_declined';
125
+ /** TS mirror of apmsg:ConsultAnswerShape (structural; the bodyHash binding is the task rail's). */
126
+ export declare function validateConsultAnswer(a: ConsultAnswerV1): ConsultAnswerValidationError[];
127
+ /** Spine SKOS lifecycle for a ConsultationIntent (spec 329 §5 / spec 239). */
128
+ export type ConsultationIntentStatus = 'drafted' | 'expressed' | 'fulfilled' | 'abandoned';
129
+ /**
130
+ * The Layer-2 DESCRIPTION record the org keeps per routed consult (spec 329 §5; org vault
131
+ * `routing.consult:<questionId>:<memberSA>`). Wire tag `ap.consultation-intent.v1` ↔
132
+ * apint:ConsultationIntent (tbox/intents.ttl; apint:ConsultationIntentShape). This record never
133
+ * executes anything — the A2A task rail does; the marketplace resolver stays uninvolved.
134
+ */
135
+ export interface ConsultationIntentV1 {
136
+ version: 'ap.consultation-intent.v1';
137
+ /** `<questionId>:<memberSA>` — one intent per consulted member. */
138
+ id: string;
139
+ /** Fixed for consultations: the org RECEIVES the answer. */
140
+ direction: 'receive';
141
+ /** The consult-answer ref/IRI once fulfilled (empty until then). */
142
+ object: string;
143
+ /** The consulting org SA (CAIP-10 or 0x). */
144
+ expressedBy: CanonicalAgentId;
145
+ /** Exactly ONE member agent (depth-1 by construction — SHACL maxCount 1). */
146
+ addressedTo: [CanonicalAgentId];
147
+ /** Anoma-CSP-shaped constraints (spec 329 §5: timeout + topic scope). */
148
+ constraints: {
149
+ timeoutMs: number;
150
+ topicId: string;
151
+ };
152
+ status: ConsultationIntentStatus;
153
+ createdAt: string;
154
+ }
155
+ export type ConsultationIntentValidationError = 'bad_version' | 'bad_direction' | 'missing_expressed_by' | 'bad_addressed_to' | 'missing_constraints' | 'bad_status';
156
+ /** TS mirror of apint:ConsultationIntentShape. */
157
+ export declare function validateConsultationIntent(i: ConsultationIntentV1): ConsultationIntentValidationError[];
158
+ //# sourceMappingURL=consult.d.ts.map