@ctliz/agent-intercom-pi 0.11.0-connect.2

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.
@@ -0,0 +1,383 @@
1
+ import { types as nodeUtilTypes } from "node:util";
2
+ import {
3
+ BOSS_CAPABILITY_FEATURE_DIGEST,
4
+ BOSS_CONTROL_ENVELOPE_VERSION,
5
+ BOSS_POLICY_SEMANTICS_HASH,
6
+ BOSS_RUN_FEATURE,
7
+ BOSS_RUN_FEATURE_CONTRACT,
8
+ BOSS_RUN_FEATURE_SEMANTICS_HASH,
9
+ BOSS_RUN_FEATURE_VERSION,
10
+ BOSS_RUN_PROTOCOL_FEATURE_CONTRACT_HASH,
11
+ BROKER_FEATURE_ATTESTATION_VERSION,
12
+ INTERCOM_BASE_PROTOCOL_VERSION,
13
+ brokerFeatureSetHash,
14
+ evaluateBrokerCompatibility,
15
+ parseBossControlEnvelope,
16
+ parseBossParticipantBinding,
17
+ parseBossParticipantCredentialEnvelope,
18
+ parseBossRunFeatureContract,
19
+ parseBrokerCapabilityAdvertisement,
20
+ type BossControlEnvelope,
21
+ type BossFeatureRegistration,
22
+ type BossParticipantBinding,
23
+ type BossParticipantCredentialEnvelope,
24
+ type BossRunFeatureContract,
25
+ type BrokerCapabilityAdvertisement,
26
+ } from "@ctliz/agent-intercom-core/boss";
27
+ import {
28
+ parseBossPolicyPrincipal,
29
+ type BossAuthorizationContext,
30
+ type BossControlKind,
31
+ type BossPrivatePrincipal,
32
+ } from "@ctliz/agent-intercom-core/boss/policy";
33
+ import {
34
+ assertExactKeys,
35
+ assertRecord,
36
+ canonicalJson,
37
+ ContractValidationError,
38
+ readHexDigest,
39
+ } from "@ctliz/agent-intercom-core/canonical";
40
+
41
+ /** Gates which must all be implemented before Pi may advertise boss-run-v1. */
42
+ export interface BossReadinessPredicates {
43
+ providerAttested: boolean;
44
+ brokerIdentityVerified: boolean;
45
+ credentialsAuthoritative: boolean;
46
+ authorityTransitionsDurable: boolean;
47
+ participantHealthIntegrated: boolean;
48
+ recipientIngressIntegrated: boolean;
49
+ }
50
+
51
+ const BOSS_READINESS_PREDICATE_KEYS = [
52
+ "providerAttested",
53
+ "brokerIdentityVerified",
54
+ "credentialsAuthoritative",
55
+ "authorityTransitionsDurable",
56
+ "participantHealthIntegrated",
57
+ "recipientIngressIntegrated",
58
+ ] as const satisfies ReadonlyArray<keyof BossReadinessPredicates>;
59
+
60
+ function assertNoProxyGraph(value: unknown, path: string): void {
61
+ const seen = new WeakSet<object>();
62
+ const visit = (candidate: unknown, candidatePath: string): void => {
63
+ if (typeof candidate !== "object" || candidate === null) return;
64
+ if (nodeUtilTypes.isProxy(candidate)) {
65
+ throw new ContractValidationError(candidatePath, "proxies are not supported");
66
+ }
67
+ if (seen.has(candidate)) return;
68
+ seen.add(candidate);
69
+ for (const key of Reflect.ownKeys(candidate)) {
70
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
71
+ if (descriptor && Object.hasOwn(descriptor, "value")) {
72
+ visit(descriptor.value, `${candidatePath}.${typeof key === "symbol" ? String(key) : key}`);
73
+ }
74
+ }
75
+ };
76
+ visit(value, path);
77
+ }
78
+
79
+ function parseBossReadinessPredicates(value: unknown): BossReadinessPredicates {
80
+ if (
81
+ typeof value !== "object"
82
+ || value === null
83
+ || nodeUtilTypes.isProxy(value)
84
+ || Array.isArray(value)
85
+ || Object.getPrototypeOf(value) !== Object.prototype
86
+ ) {
87
+ throw new ContractValidationError("$.readiness", "must be a non-proxy plain object");
88
+ }
89
+ if (
90
+ Object.getOwnPropertyNames(value).length !== BOSS_READINESS_PREDICATE_KEYS.length
91
+ || Object.getOwnPropertySymbols(value).length !== 0
92
+ ) {
93
+ throw new ContractValidationError("$.readiness", "must contain exactly the six readiness predicates");
94
+ }
95
+ for (const key of BOSS_READINESS_PREDICATE_KEYS) {
96
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
97
+ if (
98
+ descriptor === undefined
99
+ || !descriptor.enumerable
100
+ || !Object.hasOwn(descriptor, "value")
101
+ || typeof descriptor.value !== "boolean"
102
+ ) {
103
+ throw new ContractValidationError(`$.readiness.${key}`, "must be an own enumerable boolean data property");
104
+ }
105
+ }
106
+ return value as BossReadinessPredicates;
107
+ }
108
+
109
+ export const DORMANT_BOSS_READINESS: Readonly<BossReadinessPredicates> = Object.freeze({
110
+ providerAttested: false,
111
+ brokerIdentityVerified: false,
112
+ credentialsAuthoritative: false,
113
+ authorityTransitionsDurable: false,
114
+ participantHealthIntegrated: false,
115
+ recipientIngressIntegrated: false,
116
+ });
117
+
118
+ const COMPLETE_BOSS_READINESS: Readonly<BossReadinessPredicates> = Object.freeze({
119
+ providerAttested: true,
120
+ brokerIdentityVerified: true,
121
+ credentialsAuthoritative: true,
122
+ authorityTransitionsDurable: true,
123
+ participantHealthIntegrated: true,
124
+ recipientIngressIntegrated: true,
125
+ });
126
+
127
+ export function missingBossReadinessPredicates(readiness: BossReadinessPredicates): Array<keyof BossReadinessPredicates> {
128
+ const parsed = parseBossReadinessPredicates(readiness);
129
+ return BOSS_READINESS_PREDICATE_KEYS.filter((predicate) => parsed[predicate] !== true);
130
+ }
131
+
132
+ export function isBossReady(readiness: BossReadinessPredicates): boolean {
133
+ return missingBossReadinessPredicates(readiness).length === 0;
134
+ }
135
+
136
+ /** Untrusted client request. A client never gets to assert its own binding. */
137
+ export interface BossParticipantRegistrationMetadata {
138
+ featureContract: BossRunFeatureContract;
139
+ capabilityDigest: string;
140
+ credential: BossParticipantCredentialEnvelope;
141
+ }
142
+
143
+ /** Broker-owned metadata returned only after protected credential binding. */
144
+ export interface BossSessionMetadata {
145
+ binding: BossParticipantBinding;
146
+ principal: BossPrivatePrincipal;
147
+ featureContract: BossRunFeatureContract;
148
+ policySemanticsHash: string;
149
+ capabilityDigest: string;
150
+ brokerIdentityVerified: true;
151
+ }
152
+
153
+ /** Exact, descriptor-safe projection of an optional Boss registration request. */
154
+ export function parseBossParticipantRegistrationMetadata(value: unknown): BossParticipantRegistrationMetadata {
155
+ assertNoProxyGraph(value, "$.boss");
156
+ assertRecord(value, "$.boss");
157
+ assertExactKeys(value, ["featureContract", "capabilityDigest", "credential"], [], "$.boss");
158
+ const featureContract = parseBossRunFeatureContract(Object.getOwnPropertyDescriptor(value, "featureContract")!.value);
159
+ const capabilityDigest = readHexDigest(
160
+ Object.getOwnPropertyDescriptor(value, "capabilityDigest")!.value,
161
+ "$.boss.capabilityDigest",
162
+ );
163
+ const credential = parseBossParticipantCredentialEnvelope(
164
+ Object.getOwnPropertyDescriptor(value, "credential")!.value,
165
+ );
166
+ if (
167
+ canonicalJson(featureContract) !== canonicalJson(BOSS_RUN_FEATURE_CONTRACT)
168
+ || capabilityDigest !== BOSS_CAPABILITY_FEATURE_DIGEST
169
+ || credential.namespace !== BOSS_RUN_FEATURE
170
+ ) {
171
+ throw new ContractValidationError("$.boss", "must exactly request boss-run-v1 over base protocol v4");
172
+ }
173
+ return { featureContract, capabilityDigest, credential };
174
+ }
175
+
176
+ /** Exact, descriptor-safe parser for broker-owned live-session metadata. */
177
+ export function parseBossSessionMetadata(value: unknown, expectedSessionId?: string): BossSessionMetadata {
178
+ assertNoProxyGraph(value, "$.boss");
179
+ assertRecord(value, "$.boss");
180
+ assertExactKeys(value, [
181
+ "binding",
182
+ "principal",
183
+ "featureContract",
184
+ "policySemanticsHash",
185
+ "capabilityDigest",
186
+ "brokerIdentityVerified",
187
+ ], [], "$.boss");
188
+ const binding = parseBossParticipantBinding(Object.getOwnPropertyDescriptor(value, "binding")!.value);
189
+ const parsedPrincipal = parseBossPolicyPrincipal(Object.getOwnPropertyDescriptor(value, "principal")!.value);
190
+ if (parsedPrincipal.principalClass !== "boss-private") {
191
+ throw new ContractValidationError("$.boss.principal", "must be boss-private");
192
+ }
193
+ const principal: BossPrivatePrincipal = parsedPrincipal;
194
+ const featureContract = parseBossRunFeatureContract(Object.getOwnPropertyDescriptor(value, "featureContract")!.value);
195
+ const policySemanticsHash = readHexDigest(
196
+ Object.getOwnPropertyDescriptor(value, "policySemanticsHash")!.value,
197
+ "$.boss.policySemanticsHash",
198
+ );
199
+ const capabilityDigest = readHexDigest(
200
+ Object.getOwnPropertyDescriptor(value, "capabilityDigest")!.value,
201
+ "$.boss.capabilityDigest",
202
+ );
203
+ if (Object.getOwnPropertyDescriptor(value, "brokerIdentityVerified")!.value !== true) {
204
+ throw new ContractValidationError("$.boss.brokerIdentityVerified", "must be true");
205
+ }
206
+ if (expectedSessionId !== undefined && binding.sessionId !== expectedSessionId) {
207
+ throw new ContractValidationError("$.boss.binding.sessionId", "must match the broker session ID");
208
+ }
209
+ if (
210
+ binding.state !== "active"
211
+ || principal.state !== "active"
212
+ || binding.sessionId !== principal.principalId
213
+ || binding.bossRunId !== principal.bossRunId
214
+ || binding.participantId !== principal.participantId
215
+ || binding.role !== principal.role
216
+ || binding.bindingEpoch !== principal.bindingEpoch
217
+ || binding.assignedManagerParticipantId !== principal.assignedManagerParticipantId
218
+ || canonicalJson(featureContract) !== canonicalJson(BOSS_RUN_FEATURE_CONTRACT)
219
+ || policySemanticsHash !== BOSS_POLICY_SEMANTICS_HASH
220
+ || capabilityDigest !== BOSS_CAPABILITY_FEATURE_DIGEST
221
+ ) throw new ContractValidationError("$.boss", "does not describe one active, canonically attested participant");
222
+ return {
223
+ binding,
224
+ principal,
225
+ featureContract,
226
+ policySemanticsHash,
227
+ capabilityDigest,
228
+ brokerIdentityVerified: true,
229
+ };
230
+ }
231
+
232
+ export function brokerCapabilityAdvertisement(
233
+ readiness: BossReadinessPredicates = DORMANT_BOSS_READINESS,
234
+ ): BrokerCapabilityAdvertisement {
235
+ if (!isBossReady(readiness)) {
236
+ return parseBrokerCapabilityAdvertisement({
237
+ baseProtocolVersion: INTERCOM_BASE_PROTOCOL_VERSION,
238
+ features: [],
239
+ });
240
+ }
241
+ const features = [{
242
+ version: BROKER_FEATURE_ATTESTATION_VERSION,
243
+ feature: BOSS_RUN_FEATURE,
244
+ featureVersion: BOSS_RUN_FEATURE_VERSION,
245
+ semanticsHash: BOSS_RUN_FEATURE_SEMANTICS_HASH,
246
+ controlEnvelopeVersion: BOSS_CONTROL_ENVELOPE_VERSION,
247
+ capabilityDigest: BOSS_CAPABILITY_FEATURE_DIGEST,
248
+ }];
249
+ return parseBrokerCapabilityAdvertisement({
250
+ baseProtocolVersion: INTERCOM_BASE_PROTOCOL_VERSION,
251
+ features,
252
+ protocolFeatureContractHash: BOSS_RUN_PROTOCOL_FEATURE_CONTRACT_HASH,
253
+ featureSetHash: brokerFeatureSetHash(features),
254
+ controlEnvelopeVersion: BOSS_CONTROL_ENVELOPE_VERSION,
255
+ capabilityDigest: BOSS_CAPABILITY_FEATURE_DIGEST,
256
+ });
257
+ }
258
+
259
+ export type BossNegotiationDecision =
260
+ | { accepted: true; featureContract: BossRunFeatureContract }
261
+ | { accepted: false; code: "BOSS_FEATURE_NOT_ADVERTISED" | "BOSS_FEATURE_DIVERGENCE" };
262
+
263
+ /** Exact boss-run-v1/base-protocol-3 negotiation; no legacy downgrade exists. */
264
+ export function negotiateBossRegistration(
265
+ metadataValue: unknown,
266
+ advertisementValue: unknown,
267
+ ): BossNegotiationDecision {
268
+ let metadata: BossParticipantRegistrationMetadata;
269
+ let advertisement: BrokerCapabilityAdvertisement;
270
+ try {
271
+ metadata = parseBossParticipantRegistrationMetadata(metadataValue);
272
+ assertNoProxyGraph(advertisementValue, "$.capabilities");
273
+ advertisement = parseBrokerCapabilityAdvertisement(advertisementValue);
274
+ } catch {
275
+ return { accepted: false, code: "BOSS_FEATURE_DIVERGENCE" };
276
+ }
277
+ const ordinaryCompatibility = evaluateBrokerCompatibility({
278
+ clientKind: "ordinary",
279
+ supportedBaseProtocolVersions: [INTERCOM_BASE_PROTOCOL_VERSION],
280
+ }, advertisement);
281
+ if (!ordinaryCompatibility.compatible || ordinaryCompatibility.mode !== "ordinary") {
282
+ return { accepted: false, code: "BOSS_FEATURE_DIVERGENCE" };
283
+ }
284
+ const feature = advertisement.features.find((entry) => entry.feature === BOSS_RUN_FEATURE);
285
+ if (!feature) return { accepted: false, code: "BOSS_FEATURE_NOT_ADVERTISED" };
286
+ if (
287
+ canonicalJson(advertisement) !== canonicalJson(brokerCapabilityAdvertisement(COMPLETE_BOSS_READINESS))
288
+ || canonicalJson(metadata.featureContract) !== canonicalJson(BOSS_RUN_FEATURE_CONTRACT)
289
+ || metadata.capabilityDigest !== BOSS_CAPABILITY_FEATURE_DIGEST
290
+ ) return { accepted: false, code: "BOSS_FEATURE_DIVERGENCE" };
291
+ return { accepted: true, featureContract: metadata.featureContract };
292
+ }
293
+
294
+ export function bossFeatureRegistration(
295
+ principalId: string,
296
+ metadata: BossSessionMetadata,
297
+ brokerIdentityVerified: boolean,
298
+ ): BossFeatureRegistration {
299
+ const parsed = parseBossSessionMetadata(metadata, principalId);
300
+ return {
301
+ principalId,
302
+ principalClass: "boss-bound",
303
+ state: parsed.binding.state,
304
+ bossRunId: parsed.binding.bossRunId,
305
+ participantId: parsed.binding.participantId,
306
+ bindingEpoch: parsed.binding.bindingEpoch,
307
+ featureContract: parsed.featureContract,
308
+ policySemanticsHash: parsed.policySemanticsHash,
309
+ capabilityDigest: parsed.capabilityDigest,
310
+ brokerIdentityVerified,
311
+ };
312
+ }
313
+
314
+ const BOSS_CONTROL_KIND_BY_TYPE = {
315
+ "boss.assignment.created": "assignment_request",
316
+ "boss.assignment.accepted": "assignment_response",
317
+ "boss.assignment.checkpoint": "assignment_response",
318
+ "boss.assignment.submitted": "assignment_response",
319
+ "boss.assignment.rejected": "assignment_response",
320
+ "boss.assignment.cancelled": "lifecycle",
321
+ "boss.staffing.requested": "staffing",
322
+ "boss.staffing.resolved": "staffing",
323
+ "boss.review.requested": "review_request",
324
+ "boss.review.submitted": "review_result",
325
+ "boss.council.requested": "review_request",
326
+ "boss.council.submitted": "review_result",
327
+ "boss.proof.submitted": "proof",
328
+ "boss.worker.health": "health",
329
+ "boss.worker.blocked": "health",
330
+ "boss.worker.failed": "health",
331
+ "boss.worker.notice": "lifecycle",
332
+ "boss.worker.notice_delivery_failed": "lifecycle",
333
+ "boss.decision.required": "decision",
334
+ } as const satisfies Readonly<Record<BossControlEnvelope["type"], BossControlKind>>;
335
+
336
+ export function bossControlKind(control: BossControlEnvelope): BossControlKind {
337
+ return BOSS_CONTROL_KIND_BY_TYPE[control.type];
338
+ }
339
+
340
+ export function parseBossControl(value: unknown): BossControlEnvelope | null {
341
+ try {
342
+ assertNoProxyGraph(value, "$.control");
343
+ return parseBossControlEnvelope(value);
344
+ } catch {
345
+ return null;
346
+ }
347
+ }
348
+
349
+ export interface CorrelatedBossControl {
350
+ envelope: BossControlEnvelope;
351
+ context: BossAuthorizationContext;
352
+ }
353
+
354
+ export function correlateBossControl(
355
+ metadataValue: unknown,
356
+ envelopeValue: unknown,
357
+ transportMessageId: string,
358
+ ): CorrelatedBossControl | null {
359
+ try {
360
+ const metadata = parseBossSessionMetadata(metadataValue);
361
+ assertNoProxyGraph(envelopeValue, "$.control");
362
+ const envelope = parseBossControlEnvelope(envelopeValue);
363
+ if (
364
+ envelope.messageId !== transportMessageId
365
+ || envelope.bossRunId !== metadata.binding.bossRunId
366
+ || envelope.participantId !== metadata.binding.participantId
367
+ || envelope.bindingEpoch !== metadata.binding.bindingEpoch
368
+ ) return null;
369
+ return {
370
+ envelope,
371
+ context: {
372
+ actorBindingEpoch: metadata.binding.bindingEpoch,
373
+ controlKind: bossControlKind(envelope),
374
+ // Transport/envelope agreement proves identity consistency only. Pi
375
+ // has no assignment/review/lifecycle evidence authority, so it must
376
+ // never manufacture authoritative correlation from these fields.
377
+ correlated: false,
378
+ },
379
+ };
380
+ } catch {
381
+ return null;
382
+ }
383
+ }