@oxy.so/contracts 4.11.0-oxy-one.0 → 4.12.0

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 (111) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/accountGraph.js +5 -3
  3. package/dist/cjs/agency.js +178 -96
  4. package/dist/cjs/agentKeys.js +80 -26
  5. package/dist/cjs/capabilityBindings.js +2 -2
  6. package/dist/cjs/capabilityInvocation.js +3 -1
  7. package/dist/cjs/commonsSignIn.js +2 -2
  8. package/dist/cjs/deviceSession.js +5 -1
  9. package/dist/cjs/email/messages.js +70 -4
  10. package/dist/cjs/emailAgentContext.js +16 -8
  11. package/dist/cjs/externalIdentity.js +30 -12
  12. package/dist/cjs/identity.js +14 -6
  13. package/dist/cjs/identityLink.js +7 -2
  14. package/dist/cjs/identityProof.js +2 -1
  15. package/dist/cjs/index.js +12 -8
  16. package/dist/cjs/inference/catalogue.js +2 -12
  17. package/dist/cjs/inference/decisions.js +102 -83
  18. package/dist/cjs/inference/economics.js +15 -5
  19. package/dist/cjs/inference/embeddings.js +44 -6
  20. package/dist/cjs/inference/identifiers.js +14 -1
  21. package/dist/cjs/inference/inbox.js +33 -2
  22. package/dist/cjs/inference/providerConnection.js +21 -6
  23. package/dist/cjs/inference/realtime.js +114 -107
  24. package/dist/cjs/inference/routingPolicy.js +17 -0
  25. package/dist/cjs/inference/scopedExecution.js +12 -12
  26. package/dist/cjs/inference/usage.js +10 -9
  27. package/dist/cjs/inference/version.js +1 -1
  28. package/dist/cjs/notifications.js +25 -5
  29. package/dist/cjs/oauth.js +30 -14
  30. package/dist/cjs/oxyRecordTypes.js +2 -2
  31. package/dist/cjs/products/access.js +146 -57
  32. package/dist/cjs/products/billing.js +71 -17
  33. package/dist/cjs/products/checkout.js +24 -6
  34. package/dist/cjs/products/plans.js +22 -7
  35. package/dist/cjs/recommendations.js +4 -6
  36. package/dist/cjs/reputation.js +3 -6
  37. package/dist/cjs/sessionStatus.js +1 -6
  38. package/dist/cjs/signIn.js +17 -4
  39. package/dist/cjs/transparency.js +3 -1
  40. package/dist/cjs/updates.js +2 -4
  41. package/dist/cjs/userResponse.js +27 -7
  42. package/dist/cjs/username.js +3 -1
  43. package/dist/esm/.tsbuildinfo +1 -1
  44. package/dist/esm/accountGraph.js +5 -3
  45. package/dist/esm/agency.js +178 -96
  46. package/dist/esm/agentKeys.js +80 -26
  47. package/dist/esm/capabilityBindings.js +2 -2
  48. package/dist/esm/capabilityInvocation.js +3 -1
  49. package/dist/esm/commonsSignIn.js +2 -2
  50. package/dist/esm/deviceSession.js +5 -1
  51. package/dist/esm/email/messages.js +69 -3
  52. package/dist/esm/emailAgentContext.js +16 -8
  53. package/dist/esm/externalIdentity.js +30 -12
  54. package/dist/esm/identity.js +14 -6
  55. package/dist/esm/identityLink.js +7 -2
  56. package/dist/esm/identityProof.js +2 -1
  57. package/dist/esm/index.js +10 -8
  58. package/dist/esm/inference/aliaModelRelease.js +1 -1
  59. package/dist/esm/inference/catalogue.js +3 -13
  60. package/dist/esm/inference/decisions.js +108 -89
  61. package/dist/esm/inference/economics.js +16 -6
  62. package/dist/esm/inference/embeddings.js +44 -6
  63. package/dist/esm/inference/identifiers.js +13 -0
  64. package/dist/esm/inference/inbox.js +32 -1
  65. package/dist/esm/inference/providerConnection.js +21 -6
  66. package/dist/esm/inference/realtime.js +123 -116
  67. package/dist/esm/inference/routingPolicy.js +18 -1
  68. package/dist/esm/inference/scopedExecution.js +15 -15
  69. package/dist/esm/inference/usage.js +11 -10
  70. package/dist/esm/inference/version.js +1 -1
  71. package/dist/esm/notifications.js +25 -5
  72. package/dist/esm/oauth.js +30 -14
  73. package/dist/esm/oxyRecordTypes.js +2 -2
  74. package/dist/esm/products/access.js +146 -57
  75. package/dist/esm/products/billing.js +71 -17
  76. package/dist/esm/products/checkout.js +24 -6
  77. package/dist/esm/products/plans.js +22 -7
  78. package/dist/esm/recommendations.js +4 -6
  79. package/dist/esm/reputation.js +3 -6
  80. package/dist/esm/sessionStatus.js +1 -6
  81. package/dist/esm/signIn.js +17 -4
  82. package/dist/esm/transparency.js +3 -1
  83. package/dist/esm/updates.js +2 -4
  84. package/dist/esm/userResponse.js +27 -7
  85. package/dist/esm/username.js +3 -1
  86. package/dist/types/.tsbuildinfo +1 -1
  87. package/dist/types/accountGraph.d.ts +1 -1
  88. package/dist/types/accountSubject.d.ts +4 -4
  89. package/dist/types/commonsSignIn.d.ts +2 -2
  90. package/dist/types/email/messages.d.ts +208 -2
  91. package/dist/types/identity.d.ts +1 -1
  92. package/dist/types/index.d.ts +10 -10
  93. package/dist/types/inference/accountBilling.d.ts +2 -2
  94. package/dist/types/inference/decisions.d.ts +21 -1
  95. package/dist/types/inference/identifiers.d.ts +14 -0
  96. package/dist/types/inference/inbox.d.ts +129 -5
  97. package/dist/types/inference/realtime.d.ts +19 -1
  98. package/dist/types/inference/request.d.ts +54 -0
  99. package/dist/types/inference/routingPolicy.d.ts +10 -0
  100. package/dist/types/inference/scopedExecution.d.ts +1 -1
  101. package/dist/types/inference/usage.d.ts +12 -0
  102. package/dist/types/inference/version.d.ts +1 -1
  103. package/dist/types/moderationReputation.d.ts +1 -1
  104. package/dist/types/oxyRecordTypes.d.ts +2 -2
  105. package/dist/types/products/access.d.ts +102 -102
  106. package/dist/types/products/checkout.d.ts +3 -3
  107. package/dist/types/products/plans.d.ts +40 -40
  108. package/dist/types/reputation.d.ts +4 -4
  109. package/dist/types/updates.d.ts +1 -1
  110. package/dist/types/userResponse.d.ts +22 -23
  111. package/package.json +1 -2
@@ -108,7 +108,7 @@ export function isOperatorSwitchTargetKind(kind) {
108
108
  * Narrow an unknown value to an {@link AccountKind}.
109
109
  *
110
110
  * The user-DTO serializers read from structurally-permissive `unknown` sources
111
- * (a Drizzle row, a Mongo document, an already-formatted object), so each one
111
+ * (a Drizzle row, a raw document, an already-formatted object), so each one
112
112
  * would otherwise hand-roll this check and they would drift on what counts.
113
113
  */
114
114
  export function isAccountKind(value) {
@@ -386,7 +386,8 @@ const accountNameSchema = z
386
386
  * accept categories would break that reasoning silently, so
387
387
  * `__tests__/accountGraph.test.ts` asserts the two lists agree.
388
388
  */
389
- export const createAccountRequestSchema = z.object({
389
+ export const createAccountRequestSchema = z
390
+ .object({
390
391
  parentAccountId: z.string().trim().min(1).optional(),
391
392
  kind: childAccountKindSchema,
392
393
  /**
@@ -465,7 +466,8 @@ export const createAccountRequestSchema = z.object({
465
466
  * remedy must not either.
466
467
  */
467
468
  isPrivateAccount: z.boolean().optional(),
468
- }).superRefine((request, ctx) => {
469
+ })
470
+ .superRefine((request, ctx) => {
469
471
  // The ONE place `kind` and `username` arrive in the same object, so it is the
470
472
  // only place a wire schema CAN apply the per-kind half of the policy: a bot's
471
473
  // handle must end in `bot`. Not a second rule — it asks
@@ -2,17 +2,17 @@ import { z } from 'zod';
2
2
  import { catalogInvocationPathParameters, findOverlappingCatalogInvocations, } from './capabilityInvocation.js';
3
3
  const nonEmptyStringSchema = z.string().trim().min(1);
4
4
  const identifierSchema = z.string().trim().min(1).max(255);
5
- const limitKeySchema = z.string().regex(/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*$/, 'limit keys must be dot-separated input property names').max(255);
5
+ const limitKeySchema = z
6
+ .string()
7
+ .regex(/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*$/, 'limit keys must be dot-separated input property names')
8
+ .max(255);
6
9
  const auditCodeSchema = z.string().regex(/^[A-Za-z0-9_.:-]{1,128}$/);
7
10
  const sha256HexSchema = z.string().regex(/^[a-f0-9]{64}$/);
8
- const invocationPathSchema = z.string().regex(/^\/(?!\/)[^\\?#]*$/, 'invocation paths must be absolute app-local paths without backslashes, query or fragment');
11
+ const invocationPathSchema = z
12
+ .string()
13
+ .regex(/^\/(?!\/)[^\\?#]*$/, 'invocation paths must be absolute app-local paths without backslashes, query or fragment');
9
14
  /** Autonomy is ordered from least to most permissive. */
10
- export const AUTONOMY_LEVELS = [
11
- 'read_only',
12
- 'draft',
13
- 'execute_on_request',
14
- 'autonomous',
15
- ];
15
+ export const AUTONOMY_LEVELS = ['read_only', 'draft', 'execute_on_request', 'autonomous'];
16
16
  export const autonomyLevelSchema = z.enum(AUTONOMY_LEVELS);
17
17
  export const CAPABILITY_PACKAGES = [
18
18
  'read',
@@ -26,14 +26,18 @@ export const CAPABILITY_PACKAGES = [
26
26
  ];
27
27
  export const capabilityPackageSchema = z.enum(CAPABILITY_PACKAGES);
28
28
  export const actorRefSchema = z.discriminatedUnion('type', [
29
- z.object({
29
+ z
30
+ .object({
30
31
  type: z.literal('alia'),
31
32
  ownerAccountId: identifierSchema,
32
- }).strict(),
33
- z.object({
33
+ })
34
+ .strict(),
35
+ z
36
+ .object({
34
37
  type: z.literal('agent'),
35
38
  accountId: identifierSchema,
36
- }).strict(),
39
+ })
40
+ .strict(),
37
41
  ]);
38
42
  /** Present requester only; standing grants/automation retain actorRefSchema. */
39
43
  export const executionActorRefSchema = z.discriminatedUnion('type', [
@@ -41,63 +45,84 @@ export const executionActorRefSchema = z.discriminatedUnion('type', [
41
45
  z.object({ type: z.literal('requester'), accountId: identifierSchema }).strict(),
42
46
  ]);
43
47
  /** Separate bearer lives only in the SDK option / authority request body. */
44
- export const foregroundExecutionAuthorizationInputSchema = z.object({
48
+ export const foregroundExecutionAuthorizationInputSchema = z
49
+ .object({
45
50
  tool: z.enum(['recommendProfiles', 'readViewerGraph']),
46
- expectedCatalog: z.object({
51
+ expectedCatalog: z
52
+ .object({
47
53
  registrationId: identifierSchema,
48
54
  version: identifierSchema,
49
55
  digest: sha256HexSchema,
50
- }).strict(),
56
+ })
57
+ .strict(),
51
58
  runId: identifierSchema,
52
59
  stepId: identifierSchema.optional(),
53
60
  expiresAt: z.string().datetime(),
54
- }).strict();
55
- export const resourceRefSchema = z.object({
61
+ })
62
+ .strict();
63
+ export const resourceRefSchema = z
64
+ .object({
56
65
  appId: identifierSchema,
57
66
  effectiveAccountId: identifierSchema,
58
67
  resourceType: identifierSchema,
59
68
  resourceId: identifierSchema,
60
- }).strict();
61
- export const toolGrantOverrideSchema = z.object({
69
+ })
70
+ .strict();
71
+ export const toolGrantOverrideSchema = z
72
+ .object({
62
73
  tool: identifierSchema,
63
74
  decision: z.enum(['allow', 'deny']),
64
- }).strict();
65
- export const grantLimitSchema = z.object({
75
+ })
76
+ .strict();
77
+ export const grantLimitSchema = z
78
+ .object({
66
79
  tool: identifierSchema,
67
80
  key: limitKeySchema,
68
81
  // Persisted limits are deliberately closed scalar bounds. Strings and
69
82
  // arrays are tool arguments in disguise (recipient lists, prompts, search
70
83
  // queries) and ADR 0016 forbids persisting those in Oxy.
71
84
  value: z.union([z.number().finite(), z.boolean()]),
72
- }).strict();
73
- export const capabilityCatalogBindingSchema = z.object({
85
+ })
86
+ .strict();
87
+ export const capabilityCatalogBindingSchema = z
88
+ .object({
74
89
  registrationId: identifierSchema,
75
90
  version: identifierSchema,
76
91
  digest: sha256HexSchema,
77
- }).strict();
92
+ })
93
+ .strict();
78
94
  export const executionAuthorizationRefSchema = z.discriminatedUnion('kind', [
79
- z.object({
95
+ z
96
+ .object({
80
97
  kind: z.literal('direct_request'),
81
98
  id: identifierSchema,
82
- }).strict(),
83
- z.object({
99
+ })
100
+ .strict(),
101
+ z
102
+ .object({
84
103
  kind: z.literal('automation'),
85
104
  id: identifierSchema,
86
105
  automationId: identifierSchema,
87
- }).strict(),
106
+ })
107
+ .strict(),
88
108
  ]);
89
- export const capabilityCoordinatorSchema = z.object({
109
+ export const capabilityCoordinatorSchema = z
110
+ .object({
90
111
  applicationId: identifierSchema,
91
112
  credentialId: identifierSchema,
92
- }).strict();
113
+ })
114
+ .strict();
93
115
  /** Opt-in catalogue pin; legacy issuance omits expectedCatalog and its claim. */
94
- export const capabilityTicketRequestSchema = z.object({
116
+ export const capabilityTicketRequestSchema = z
117
+ .object({
95
118
  executionAuthorizationId: z.string().min(1),
96
119
  runId: z.string().min(1).optional(),
97
120
  stepId: z.string().min(1).optional(),
98
121
  expectedCatalog: capabilityCatalogBindingSchema.optional(),
99
- }).strict();
100
- export const delegationGrantSchema = z.object({
122
+ })
123
+ .strict();
124
+ export const delegationGrantSchema = z
125
+ .object({
101
126
  id: identifierSchema,
102
127
  ownerAccountId: identifierSchema,
103
128
  actor: actorRefSchema,
@@ -113,30 +138,38 @@ export const delegationGrantSchema = z.object({
113
138
  revokedAt: z.string().datetime().nullable().default(null),
114
139
  createdAt: z.string().datetime(),
115
140
  updatedAt: z.string().datetime(),
116
- }).strict();
141
+ })
142
+ .strict();
117
143
  export const automationTriggerSchema = z.discriminatedUnion('type', [
118
144
  z.object({ type: z.literal('manual') }).strict(),
119
- z.object({
145
+ z
146
+ .object({
120
147
  type: z.literal('event'),
121
148
  appId: identifierSchema,
122
149
  eventType: identifierSchema,
123
150
  resource: resourceRefSchema.optional(),
124
- }).strict(),
125
- z.object({
151
+ })
152
+ .strict(),
153
+ z
154
+ .object({
126
155
  type: z.literal('schedule'),
127
156
  cron: nonEmptyStringSchema,
128
157
  timezone: nonEmptyStringSchema,
129
- }).strict(),
158
+ })
159
+ .strict(),
130
160
  ]);
131
161
  export const automationActorSelectionSchema = z.discriminatedUnion('mode', [
132
162
  z.object({ mode: z.literal('fixed'), actor: actorRefSchema }).strict(),
133
163
  z.object({ mode: z.literal('automatic') }).strict(),
134
164
  ]);
135
- export const automationDataFlowSchema = z.object({
165
+ export const automationDataFlowSchema = z
166
+ .object({
136
167
  sources: z.array(resourceRefSchema),
137
168
  destinations: z.array(resourceRefSchema),
138
- }).strict();
139
- export const automationDefinitionSchema = z.object({
169
+ })
170
+ .strict();
171
+ export const automationDefinitionSchema = z
172
+ .object({
140
173
  id: identifierSchema,
141
174
  ownerAccountId: identifierSchema,
142
175
  objective: nonEmptyStringSchema,
@@ -150,8 +183,10 @@ export const automationDefinitionSchema = z.object({
150
183
  enabled: z.boolean(),
151
184
  createdAt: z.string().datetime(),
152
185
  updatedAt: z.string().datetime(),
153
- }).strict();
154
- export const capabilityTicketClaimsSchema = z.object({
186
+ })
187
+ .strict();
188
+ export const capabilityTicketClaimsSchema = z
189
+ .object({
155
190
  iss: nonEmptyStringSchema,
156
191
  aud: identifierSchema,
157
192
  sub: identifierSchema,
@@ -174,10 +209,10 @@ export const capabilityTicketClaimsSchema = z.object({
174
209
  capabilities: z.array(identifierSchema).min(1),
175
210
  limits: z.array(grantLimitSchema).default([]),
176
211
  autonomy: autonomyLevelSchema,
177
- }).strict().superRefine((claims, context) => {
178
- const expectedSubject = claims.actor.type !== 'alia'
179
- ? claims.actor.accountId
180
- : `alia:${claims.actor.ownerAccountId}`;
212
+ })
213
+ .strict()
214
+ .superRefine((claims, context) => {
215
+ const expectedSubject = claims.actor.type !== 'alia' ? claims.actor.accountId : `alia:${claims.actor.ownerAccountId}`;
181
216
  if (claims.sub !== expectedSubject) {
182
217
  context.addIssue({
183
218
  code: z.ZodIssueCode.custom,
@@ -192,13 +227,17 @@ export const capabilityTicketClaimsSchema = z.object({
192
227
  path: ['actor', 'ownerAccountId'],
193
228
  });
194
229
  }
195
- if (claims.actor.type === 'requester' && (claims.actor.accountId !== claims.requesterAccountId
196
- || claims.executionAuthorization.kind !== 'direct_request'
197
- || claims.autonomy !== 'read_only'
198
- || claims.grantId !== undefined
199
- || claims.automationId !== undefined)) {
200
- context.addIssue({ code: z.ZodIssueCode.custom, path: ['actor'],
201
- message: 'requester actors require their exact principal and direct read-only authority without standing grants' });
230
+ if (claims.actor.type === 'requester' &&
231
+ (claims.actor.accountId !== claims.requesterAccountId ||
232
+ claims.executionAuthorization.kind !== 'direct_request' ||
233
+ claims.autonomy !== 'read_only' ||
234
+ claims.grantId !== undefined ||
235
+ claims.automationId !== undefined)) {
236
+ context.addIssue({
237
+ code: z.ZodIssueCode.custom,
238
+ path: ['actor'],
239
+ message: 'requester actors require their exact principal and direct read-only authority without standing grants',
240
+ });
202
241
  }
203
242
  if (claims.exp <= claims.iat) {
204
243
  context.addIssue({
@@ -235,7 +274,8 @@ export const capabilityTicketClaimsSchema = z.object({
235
274
  });
236
275
  /** Structural projections only: an authenticated transport must produce these. */
237
276
  export const invocationPrincipalSchema = z.discriminatedUnion('kind', [
238
- z.object({
277
+ z
278
+ .object({
239
279
  kind: z.literal('oauth'),
240
280
  subject: identifierSchema,
241
281
  clientId: identifierSchema,
@@ -243,25 +283,33 @@ export const invocationPrincipalSchema = z.discriminatedUnion('kind', [
243
283
  activeAccountId: identifierSchema,
244
284
  scopes: z.array(identifierSchema),
245
285
  resource: z.string().url(),
246
- }).strict(),
247
- z.object({
286
+ })
287
+ .strict(),
288
+ z
289
+ .object({
248
290
  kind: z.literal('capability'),
249
291
  claims: capabilityTicketClaimsSchema.refine((claims) => claims.catalog !== undefined, {
250
292
  message: 'internal MCP requires a signed catalogue binding',
251
293
  }),
252
- }).strict(),
294
+ })
295
+ .strict(),
253
296
  ]);
254
- export const policyDecisionSchema = z.object({
297
+ export const policyDecisionSchema = z
298
+ .object({
255
299
  allowed: z.boolean(),
256
300
  reason: identifierSchema,
257
301
  effectiveAutonomy: autonomyLevelSchema.optional(),
258
302
  grantId: identifierSchema.optional(),
259
- }).strict();
260
- export const auditResultSchema = z.object({
303
+ })
304
+ .strict();
305
+ export const auditResultSchema = z
306
+ .object({
261
307
  status: z.enum(['planned', 'allowed', 'denied', 'succeeded', 'failed', 'rolled_back']),
262
308
  code: auditCodeSchema.optional(),
263
- }).strict();
264
- export const auditEventSchema = z.object({
309
+ })
310
+ .strict();
311
+ export const auditEventSchema = z
312
+ .object({
265
313
  eventId: identifierSchema,
266
314
  occurredAt: z.string().datetime(),
267
315
  requesterAccountId: identifierSchema,
@@ -274,20 +322,26 @@ export const auditEventSchema = z.object({
274
322
  capabilities: z.array(identifierSchema),
275
323
  policyDecision: policyDecisionSchema,
276
324
  result: auditResultSchema,
277
- rollback: z.object({
325
+ rollback: z
326
+ .object({
278
327
  supported: z.boolean(),
279
328
  attempted: z.boolean(),
280
329
  succeeded: z.boolean().optional(),
281
- }).strict(),
282
- correlation: z.object({
330
+ })
331
+ .strict(),
332
+ correlation: z
333
+ .object({
283
334
  runId: identifierSchema,
284
335
  stepId: identifierSchema.optional(),
285
336
  automationId: identifierSchema.optional(),
286
337
  idempotencyKeyHash: sha256HexSchema.optional(),
287
338
  capabilityTicketId: identifierSchema.optional(),
288
- }).strict(),
289
- }).strict();
290
- export const catalogToolSchema = z.object({
339
+ })
340
+ .strict(),
341
+ })
342
+ .strict();
343
+ export const catalogToolSchema = z
344
+ .object({
291
345
  name: identifierSchema,
292
346
  version: identifierSchema,
293
347
  description: nonEmptyStringSchema,
@@ -300,15 +354,23 @@ export const catalogToolSchema = z.object({
300
354
  idempotency: z.enum(['none', 'supported', 'required']),
301
355
  rollback: z.enum(['none', 'manual', 'supported']),
302
356
  exposure: z.array(z.enum(['internal', 'mcp'])).min(1),
303
- limitKeys: z.array(z.object({
357
+ limitKeys: z
358
+ .array(z
359
+ .object({
304
360
  key: limitKeySchema,
305
361
  kind: z.enum(['maximum_number', 'exact_boolean']),
306
- }).strict()).default([]),
307
- invocation: z.object({
362
+ })
363
+ .strict())
364
+ .default([]),
365
+ invocation: z
366
+ .object({
308
367
  method: z.enum(['GET', 'POST', 'PATCH', 'PUT', 'DELETE']),
309
368
  path: invocationPathSchema,
310
- }).strict(),
311
- }).strict().superRefine((tool, context) => {
369
+ })
370
+ .strict(),
371
+ })
372
+ .strict()
373
+ .superRefine((tool, context) => {
312
374
  const requireUnique = (values, path) => {
313
375
  if (new Set(values).size !== values.length) {
314
376
  context.addIssue({
@@ -385,7 +447,8 @@ export const catalogToolSchema = z.object({
385
447
  path: ['capabilityPackage'],
386
448
  });
387
449
  }
388
- if ((tool.effect === 'financial' || tool.effect === 'security') && tool.idempotency !== 'required') {
450
+ if ((tool.effect === 'financial' || tool.effect === 'security') &&
451
+ tool.idempotency !== 'required') {
389
452
  context.addIssue({
390
453
  code: z.ZodIssueCode.custom,
391
454
  message: 'Financial and security effects require idempotency keys',
@@ -404,16 +467,17 @@ export const catalogToolSchema = z.object({
404
467
  // not declare as a REQUIRED property can never be filled, and a GET input
405
468
  // that is not a scalar has no query-string form — both are refused here so
406
469
  // the builder never has to guess.
407
- const declared = typeof tool.inputSchema.properties === 'object'
408
- && tool.inputSchema.properties !== null
409
- && !Array.isArray(tool.inputSchema.properties)
470
+ const declared = typeof tool.inputSchema.properties === 'object' &&
471
+ tool.inputSchema.properties !== null &&
472
+ !Array.isArray(tool.inputSchema.properties)
410
473
  ? tool.inputSchema.properties
411
474
  : {};
412
475
  const required = Array.isArray(tool.inputSchema.required) ? tool.inputSchema.required : [];
413
476
  const parameters = catalogInvocationPathParameters(tool.invocation.path);
414
477
  requireUnique(parameters, 'invocation.path parameters');
415
478
  for (const parameter of parameters) {
416
- if (!Object.prototype.hasOwnProperty.call(declared, parameter) || !required.includes(parameter)) {
479
+ if (!Object.prototype.hasOwnProperty.call(declared, parameter) ||
480
+ !required.includes(parameter)) {
417
481
  context.addIssue({
418
482
  code: z.ZodIssueCode.custom,
419
483
  message: `Path parameter {${parameter}} must be a required input property`,
@@ -436,20 +500,26 @@ export const catalogToolSchema = z.object({
436
500
  }
437
501
  }
438
502
  });
439
- export const catalogEventSchema = z.object({
503
+ export const catalogEventSchema = z
504
+ .object({
440
505
  type: identifierSchema,
441
506
  version: identifierSchema,
442
507
  description: nonEmptyStringSchema,
443
508
  dataSchema: z.record(z.unknown()),
444
509
  resourceTypes: z.array(identifierSchema).min(1),
445
- }).strict();
446
- export const appCapabilityCatalogSchema = z.object({
510
+ })
511
+ .strict();
512
+ export const appCapabilityCatalogSchema = z
513
+ .object({
447
514
  schemaVersion: z.literal('1'),
448
515
  appId: identifierSchema,
449
516
  version: identifierSchema,
450
517
  audience: identifierSchema,
451
518
  /** HTTPS origin that serves the catalog's internal invocation paths. */
452
- internalBaseUrl: z.string().url().superRefine((value, context) => {
519
+ internalBaseUrl: z
520
+ .string()
521
+ .url()
522
+ .superRefine((value, context) => {
453
523
  const url = new URL(value);
454
524
  const localDevelopment = url.hostname === 'localhost' || url.hostname === '127.0.0.1';
455
525
  if (url.protocol !== 'https:' && !(localDevelopment && url.protocol === 'http:')) {
@@ -468,12 +538,16 @@ export const appCapabilityCatalogSchema = z.object({
468
538
  /** Account-scoped resource used for native Alia bindings without app-specific code. */
469
539
  accountResourceType: identifierSchema,
470
540
  /** Canonical protected-resource URI when this catalog is also exposed as an external MCP server. */
471
- externalMcp: z.object({
472
- resource: z.string().url().superRefine((value, context) => {
541
+ externalMcp: z
542
+ .object({
543
+ resource: z
544
+ .string()
545
+ .url()
546
+ .superRefine((value, context) => {
473
547
  const url = new URL(value);
474
- const localDevelopment = url.hostname === 'localhost'
475
- || url.hostname === '127.0.0.1'
476
- || url.hostname === '[::1]';
548
+ const localDevelopment = url.hostname === 'localhost' ||
549
+ url.hostname === '127.0.0.1' ||
550
+ url.hostname === '[::1]';
477
551
  if (url.protocol !== 'https:' && !(localDevelopment && url.protocol === 'http:')) {
478
552
  context.addIssue({
479
553
  code: z.ZodIssueCode.custom,
@@ -487,10 +561,14 @@ export const appCapabilityCatalogSchema = z.object({
487
561
  });
488
562
  }
489
563
  }),
490
- }).strict().optional(),
564
+ })
565
+ .strict()
566
+ .optional(),
491
567
  tools: z.array(catalogToolSchema),
492
568
  events: z.array(catalogEventSchema),
493
- }).strict().superRefine((catalog, context) => {
569
+ })
570
+ .strict()
571
+ .superRefine((catalog, context) => {
494
572
  const names = new Set();
495
573
  for (const [index, tool] of catalog.tools.entries()) {
496
574
  if (names.has(tool.name)) {
@@ -509,8 +587,8 @@ export const appCapabilityCatalogSchema = z.object({
509
587
  for (const [left, right] of findOverlappingCatalogInvocations(catalog.tools)) {
510
588
  context.addIssue({
511
589
  code: z.ZodIssueCode.custom,
512
- message: `Tools ${left.name} and ${right.name} have overlapping invocations `
513
- + `(${left.invocation.method} ${left.invocation.path} / ${right.invocation.method} ${right.invocation.path})`,
590
+ message: `Tools ${left.name} and ${right.name} have overlapping invocations ` +
591
+ `(${left.invocation.method} ${left.invocation.path} / ${right.invocation.method} ${right.invocation.path})`,
514
592
  path: ['tools'],
515
593
  });
516
594
  }
@@ -526,13 +604,16 @@ export const appCapabilityCatalogSchema = z.object({
526
604
  eventTypes.add(event.type);
527
605
  }
528
606
  });
529
- export const catalogRegistrationSchema = z.object({
607
+ export const catalogRegistrationSchema = z
608
+ .object({
530
609
  catalog: appCapabilityCatalogSchema,
531
610
  digest: z.string().regex(/^[a-f0-9]{64}$/),
532
611
  signature: nonEmptyStringSchema,
533
612
  deployedAt: z.string().datetime(),
534
- }).strict();
535
- export const normalizedAppEventSchema = z.object({
613
+ })
614
+ .strict();
615
+ export const normalizedAppEventSchema = z
616
+ .object({
536
617
  eventId: identifierSchema,
537
618
  appId: identifierSchema,
538
619
  accountId: identifierSchema,
@@ -540,4 +621,5 @@ export const normalizedAppEventSchema = z.object({
540
621
  type: identifierSchema,
541
622
  occurredAt: z.string().datetime(),
542
623
  data: z.record(z.unknown()),
543
- }).strict();
624
+ })
625
+ .strict();
@@ -4,8 +4,15 @@ import { reauthProofSchema } from './signIn.js';
4
4
  import { canonicalJson } from './identityProof.js';
5
5
  export const AGENT_PROOF_AUDIENCE = 'oxy-api/agent';
6
6
  export const AGENT_PROOF_TTL_MS = 60000;
7
- export const AGENT_PROOF_ACTIONS = ['agent_signin', 'agent_enroll', 'agent_rotate', 'agent_recover', 'agent_governance'];
8
- export const agentProofClaimsSchema = z.object({
7
+ export const AGENT_PROOF_ACTIONS = [
8
+ 'agent_signin',
9
+ 'agent_enroll',
10
+ 'agent_rotate',
11
+ 'agent_recover',
12
+ 'agent_governance',
13
+ ];
14
+ export const agentProofClaimsSchema = z
15
+ .object({
9
16
  version: z.literal(1),
10
17
  audience: z.literal(AGENT_PROOF_AUDIENCE),
11
18
  action: z.enum(AGENT_PROOF_ACTIONS),
@@ -16,48 +23,95 @@ export const agentProofClaimsSchema = z.object({
16
23
  payloadDigest: z.string().regex(/^[0-9a-f]{64}$/),
17
24
  challenge: z.string().regex(/^[0-9a-f]{64}$/),
18
25
  expiresAt: z.number().int().positive(),
19
- }).strict();
26
+ })
27
+ .strict();
20
28
  /** Different proof roles cannot substitute for one another on the same operation. */
21
29
  export function buildAgentProofMessage(claims, timestamp, role = 'credential') {
22
- return canonicalJson({ domain: 'oxy-agent-proof', ...agentProofClaimsSchema.parse(claims), timestamp, role });
30
+ return canonicalJson({
31
+ domain: 'oxy-agent-proof',
32
+ ...agentProofClaimsSchema.parse(claims),
33
+ timestamp,
34
+ role,
35
+ });
23
36
  }
24
- export const agentSignatureSchema = z.object({
37
+ export const agentSignatureSchema = z
38
+ .object({
25
39
  challenge: z.string().regex(/^[0-9a-f]{64}$/),
26
- signature: z.string().regex(/^[0-9a-f]+$/i).max(160),
40
+ signature: z
41
+ .string()
42
+ .regex(/^[0-9a-f]+$/i)
43
+ .max(160),
27
44
  timestamp: z.number().int().positive(),
28
- }).strict();
29
- export const agentChallengeRequestSchema = z.object({ publicKey: z.string().trim().min(1).max(130) }).strict();
30
- export const agentVerifyRequestSchema = agentSignatureSchema.extend({ publicKey: z.string().trim().min(1).max(130) }).strict();
31
- const newKey = { publicKey: z.string().trim().min(1).max(130), label: z.string().trim().min(1).max(120) };
45
+ })
46
+ .strict();
47
+ export const agentChallengeRequestSchema = z
48
+ .object({ publicKey: z.string().trim().min(1).max(130) })
49
+ .strict();
50
+ export const agentVerifyRequestSchema = agentSignatureSchema
51
+ .extend({ publicKey: z.string().trim().min(1).max(130) })
52
+ .strict();
53
+ const newKey = {
54
+ publicKey: z.string().trim().min(1).max(130),
55
+ label: z.string().trim().min(1).max(120),
56
+ };
32
57
  export const agentKeyOperationSchema = z.discriminatedUnion('operation', [
33
58
  z.object({ operation: z.literal('enroll'), ...newKey }).strict(),
34
59
  z.object({ operation: z.literal('recover'), ...newKey }).strict(),
35
- z.object({ operation: z.literal('rotate'), ...newKey, retireCurrent: z.boolean().optional() }).strict(),
60
+ z
61
+ .object({ operation: z.literal('rotate'), ...newKey, retireCurrent: z.boolean().optional() })
62
+ .strict(),
36
63
  z.object({ operation: z.literal('revoke'), methodId: z.string().min(1) }).strict(),
37
64
  ]);
38
- export const agentKeyOperationProofSchema = z.object({
65
+ export const agentKeyOperationProofSchema = z
66
+ .object({
39
67
  challenge: z.string().regex(/^[0-9a-f]{64}$/),
40
68
  timestamp: z.number().int().positive(),
41
- keySignature: z.string().regex(/^[0-9a-f]+$/i).max(160).optional(),
42
- governorSignature: z.string().regex(/^[0-9a-f]+$/i).max(160).optional(),
69
+ keySignature: z
70
+ .string()
71
+ .regex(/^[0-9a-f]+$/i)
72
+ .max(160)
73
+ .optional(),
74
+ governorSignature: z
75
+ .string()
76
+ .regex(/^[0-9a-f]+$/i)
77
+ .max(160)
78
+ .optional(),
43
79
  reauth: reauthProofSchema.optional(),
44
- }).strict();
45
- export const executeAgentKeyOperationSchema = z.object({
80
+ })
81
+ .strict();
82
+ export const executeAgentKeyOperationSchema = z
83
+ .object({
46
84
  operation: agentKeyOperationSchema,
47
85
  proof: agentKeyOperationProofSchema,
48
- }).strict();
49
- export const agentKeyOperationChallengeSchema = z.object({
86
+ })
87
+ .strict();
88
+ export const agentKeyOperationChallengeSchema = z
89
+ .object({
50
90
  claims: agentProofClaimsSchema,
51
91
  governorPublicKey: z.string().nullable(),
52
- }).strict();
53
- export const agentKeyOperationResultSchema = z.object({
92
+ })
93
+ .strict();
94
+ export const agentKeyOperationResultSchema = z
95
+ .object({
54
96
  methodId: z.string().nullable(),
55
97
  revokedMethodIds: z.array(z.string()),
56
- }).strict();
98
+ })
99
+ .strict();
57
100
  export const ACCOUNT_AUTH_METHODS = ['identity', 'agent_key'];
58
101
  /** Public credential inventory. Never includes a proof, bearer or private key. */
59
- export const agentKeyListResponseSchema = z.object({ keys: z.array(z.object({
60
- id: z.string(), publicKey: z.string(), label: z.string(),
61
- enrolledByUserId: z.string().nullable(), enrollmentMethod: z.enum(['governor', 'rotation', 'recovery']),
62
- linkedAt: z.string().datetime(), lastUsedAt: z.string().datetime().nullable(), revokedAt: z.string().datetime().nullable(),
63
- }).strict()) }).strict();
102
+ export const agentKeyListResponseSchema = z
103
+ .object({
104
+ keys: z.array(z
105
+ .object({
106
+ id: z.string(),
107
+ publicKey: z.string(),
108
+ label: z.string(),
109
+ enrolledByUserId: z.string().nullable(),
110
+ enrollmentMethod: z.enum(['governor', 'rotation', 'recovery']),
111
+ linkedAt: z.string().datetime(),
112
+ lastUsedAt: z.string().datetime().nullable(),
113
+ revokedAt: z.string().datetime().nullable(),
114
+ })
115
+ .strict()),
116
+ })
117
+ .strict();