@sequenceholdings/agent-spec 0.1.1 → 0.1.3

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 (72) hide show
  1. package/README.md +93 -0
  2. package/dist/agent-definition.d.ts +616 -0
  3. package/dist/agent-definition.js +240 -0
  4. package/dist/canonical-json.d.ts +2 -0
  5. package/dist/canonical-json.js +13 -0
  6. package/dist/index.d.ts +2 -117
  7. package/dist/index.js +2 -248
  8. package/dist/input-schema.d.ts +19 -0
  9. package/dist/input-schema.js +57 -0
  10. package/dist/voice-access.d.ts +40 -0
  11. package/dist/voice-access.js +34 -0
  12. package/dist/voice-actions-contracts.d.ts +423 -0
  13. package/dist/voice-actions-contracts.js +95 -0
  14. package/dist/voice-actions-transitions.d.ts +52 -0
  15. package/dist/voice-actions-transitions.js +170 -0
  16. package/dist/voice-actions.d.ts +2 -0
  17. package/dist/voice-actions.js +2 -0
  18. package/dist/voice-api.d.ts +1102 -0
  19. package/dist/voice-api.js +164 -0
  20. package/dist/voice-authoring.d.ts +463 -0
  21. package/dist/voice-authoring.js +132 -0
  22. package/dist/voice-authority-contracts.d.ts +247 -0
  23. package/dist/voice-authority-contracts.js +177 -0
  24. package/dist/voice-authority-evaluation.d.ts +29 -0
  25. package/dist/voice-authority-evaluation.js +80 -0
  26. package/dist/voice-authority-verification.d.ts +47 -0
  27. package/dist/voice-authority-verification.js +184 -0
  28. package/dist/voice-authority.d.ts +3 -0
  29. package/dist/voice-authority.js +3 -0
  30. package/dist/voice-common.d.ts +21 -0
  31. package/dist/voice-common.js +23 -0
  32. package/dist/voice-drafts.d.ts +441 -0
  33. package/dist/voice-drafts.js +75 -0
  34. package/dist/voice-grant.d.ts +19 -0
  35. package/dist/voice-grant.js +21 -0
  36. package/dist/voice-lifecycle-control.d.ts +130 -0
  37. package/dist/voice-lifecycle-control.js +138 -0
  38. package/dist/voice-lifecycle-session.d.ts +168 -0
  39. package/dist/voice-lifecycle-session.js +114 -0
  40. package/dist/voice-lifecycle-states.d.ts +96 -0
  41. package/dist/voice-lifecycle-states.js +139 -0
  42. package/dist/voice-lifecycle.d.ts +3 -0
  43. package/dist/voice-lifecycle.js +3 -0
  44. package/dist/voice-policy-duration.d.ts +46 -0
  45. package/dist/voice-policy-duration.js +166 -0
  46. package/dist/voice-policy-limits.d.ts +174 -0
  47. package/dist/voice-policy-limits.js +188 -0
  48. package/dist/voice-policy.d.ts +2 -0
  49. package/dist/voice-policy.js +2 -0
  50. package/dist/voice-provider-evidence.d.ts +80 -0
  51. package/dist/voice-provider-evidence.js +115 -0
  52. package/dist/voice-provider-publication.d.ts +319 -0
  53. package/dist/voice-provider-publication.js +117 -0
  54. package/dist/voice-provider-release.d.ts +386 -0
  55. package/dist/voice-provider-release.js +154 -0
  56. package/dist/voice-provider.d.ts +3 -0
  57. package/dist/voice-provider.js +3 -0
  58. package/dist/voice-release.d.ts +808 -0
  59. package/dist/voice-release.js +110 -0
  60. package/dist/voice-runs-audio.d.ts +157 -0
  61. package/dist/voice-runs-audio.js +85 -0
  62. package/dist/voice-runs-evidence.d.ts +183 -0
  63. package/dist/voice-runs-evidence.js +154 -0
  64. package/dist/voice-runs-model.d.ts +967 -0
  65. package/dist/voice-runs-model.js +199 -0
  66. package/dist/voice-runs-tooling.d.ts +88 -0
  67. package/dist/voice-runs-tooling.js +100 -0
  68. package/dist/voice-runs.d.ts +4 -0
  69. package/dist/voice-runs.js +4 -0
  70. package/dist/voice.d.ts +13 -0
  71. package/dist/voice.js +13 -0
  72. package/package.json +8 -3
@@ -0,0 +1,132 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { canonicalJson } from './canonical-json.js';
4
+ import { isReservedVoiceVariable, voiceHashSchema, voiceIdSchema, voiceLocalKeySchema } from './voice-common.js';
5
+ const compareKeys = (a, b) => a < b ? -1 : a > b ? 1 : 0;
6
+ const fieldSchema = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,63}$/).refine((name) => !isReservedVoiceVariable({ name }) && !['__proto__', 'constructor', 'prototype'].includes(name), 'Reserved Voice field');
7
+ const uniqueKeysSchema = z.array(voiceLocalKeySchema).max(64)
8
+ .refine((keys) => new Set(keys).size === keys.length, 'Duplicate references are not allowed')
9
+ .transform((keys) => [...keys].sort(compareKeys));
10
+ export function hashVoiceSkillContent({ name, instructions }) {
11
+ return createHash('sha256').update('sequence-voice-skill-content-v1\0')
12
+ .update(canonicalJson({ name, instructions })).digest('hex');
13
+ }
14
+ export const capturedVoiceProcedureSchema = z.strictObject({
15
+ key: voiceLocalKeySchema,
16
+ name: z.string().trim().min(1).max(200),
17
+ instructions: z.string().min(1).max(100_000).refine((text) => text.trim().length > 0, 'Instructions must contain text'),
18
+ activationDescription: z.string().trim().max(4_000),
19
+ source: z.strictObject({ skillId: voiceIdSchema, contentHash: voiceHashSchema.optional() }),
20
+ toolAliases: uniqueKeysSchema.default([]),
21
+ subprocedures: uniqueKeysSchema.default([]),
22
+ }).transform((procedure) => ({ ...procedure, source: {
23
+ skillId: procedure.source.skillId,
24
+ contentHash: hashVoiceSkillContent({ name: procedure.name, instructions: procedure.instructions }),
25
+ } }));
26
+ export const voiceAuthoredToolSchema = z.strictObject({
27
+ alias: voiceLocalKeySchema.refine((name) => !isReservedVoiceVariable({ name }), 'Reserved Voice alias'),
28
+ description: z.string().trim().min(1).max(4_000),
29
+ managedFunction: z.strictObject({
30
+ ref: z.string().max(200).regex(/^[a-z0-9][a-z0-9_-]*(?:\/[a-z0-9][a-z0-9_-]*)*$/),
31
+ operation: voiceLocalKeySchema,
32
+ }),
33
+ inputMappings: z.array(z.strictObject({ argument: fieldSchema, parameter: fieldSchema })).max(64).default([]),
34
+ outputMappings: z.array(z.strictObject({ field: fieldSchema, result: fieldSchema })).max(64).default([]),
35
+ }).superRefine((tool, context) => {
36
+ for (const [name, keys] of [
37
+ ['inputMappings', tool.inputMappings.map((item) => item.argument)],
38
+ ['inputMappings', tool.inputMappings.map((item) => item.parameter)],
39
+ ['outputMappings', tool.outputMappings.map((item) => item.field)],
40
+ ['outputMappings', tool.outputMappings.map((item) => item.result)],
41
+ ]) {
42
+ if (new Set(keys).size !== keys.length)
43
+ context.addIssue({ code: 'custom', path: [name], message: 'Duplicate mapping field' });
44
+ }
45
+ }).transform((tool) => ({ ...tool,
46
+ inputMappings: [...tool.inputMappings].sort((a, b) => compareKeys(a.argument, b.argument)),
47
+ outputMappings: [...tool.outputMappings].sort((a, b) => compareKeys(a.result, b.result)),
48
+ }));
49
+ const voiceDeclarationBaseSchema = z.strictObject({
50
+ schemaVersion: z.literal('1'),
51
+ voice: voiceIdSchema,
52
+ language: z.string().regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/).max(35),
53
+ firstMessage: z.string().trim().min(1).max(4_000),
54
+ procedures: z.array(capturedVoiceProcedureSchema).max(32).default([]),
55
+ tools: z.array(voiceAuthoredToolSchema).max(64).default([]),
56
+ });
57
+ function validateProcedureDependencies({ voice, context, }) {
58
+ const keys = new Set(voice.procedures.map((item) => item.key));
59
+ const aliases = new Set(voice.tools.map((item) => item.alias));
60
+ const referencedProcedures = new Set(voice.procedures.flatMap((item) => item.subprocedures));
61
+ if (keys.size !== voice.procedures.length)
62
+ context.addIssue({ code: 'custom', path: ['procedures'], message: 'Duplicate procedure key' });
63
+ if (new Set(voice.procedures.map((item) => item.source.skillId)).size !== voice.procedures.length) {
64
+ context.addIssue({ code: 'custom', path: ['procedures'], message: 'Capture each native Skill once' });
65
+ }
66
+ if (aliases.size !== voice.tools.length)
67
+ context.addIssue({ code: 'custom', path: ['tools'], message: 'Duplicate tool alias' });
68
+ for (const [index, procedure] of voice.procedures.entries()) {
69
+ if (procedure.activationDescription === '' && !referencedProcedures.has(procedure.key)) {
70
+ context.addIssue({ code: 'custom', path: ['procedures', index, 'activationDescription'],
71
+ message: 'An empty activation description requires a reference from another procedure' });
72
+ }
73
+ for (const [field, references, declared] of [
74
+ ['toolAliases', procedure.toolAliases, aliases], ['subprocedures', procedure.subprocedures, keys],
75
+ ]) {
76
+ for (const reference of references)
77
+ if (!declared.has(reference)) {
78
+ context.addIssue({ code: 'custom', path: ['procedures', index, field], message: `Undeclared reference: ${reference}` });
79
+ }
80
+ }
81
+ }
82
+ const byKey = new Map(voice.procedures.map((item) => [item.key, item]));
83
+ const visited = new Set();
84
+ const active = new Set();
85
+ function hasCycle(key) {
86
+ if (active.has(key))
87
+ return true;
88
+ if (visited.has(key))
89
+ return false;
90
+ active.add(key);
91
+ for (const child of byKey.get(key)?.subprocedures ?? [])
92
+ if (hasCycle(child))
93
+ return true;
94
+ active.delete(key);
95
+ visited.add(key);
96
+ return false;
97
+ }
98
+ if ([...keys].some(hasCycle))
99
+ context.addIssue({ code: 'custom', path: ['procedures'], message: 'Cyclic subprocedure reference' });
100
+ }
101
+ export const voiceDeclarationSchema = voiceDeclarationBaseSchema
102
+ .superRefine((voice, context) => validateProcedureDependencies({ voice, context }))
103
+ .transform((voice) => ({ ...voice,
104
+ procedures: [...voice.procedures].sort((a, b) => compareKeys(a.key, b.key)),
105
+ tools: [...voice.tools].sort((a, b) => compareKeys(a.alias, b.alias)),
106
+ }));
107
+ export const voiceSupportedAuthoringOptionsSchema = z.strictObject({
108
+ voices: z.array(voiceIdSchema),
109
+ languages: z.array(z.string().min(1)),
110
+ models: z.array(z.strictObject({ provider: voiceIdSchema, name: voiceIdSchema })),
111
+ });
112
+ export function validateVoiceAuthoringOptions({ voice, model, supported }) {
113
+ if (!supported.voices.includes(voice.voice))
114
+ throw new Error('Unsupported Voice selection');
115
+ if (!supported.languages.includes(voice.language))
116
+ throw new Error('Unsupported Voice language');
117
+ if (!supported.models.some((option) => option.provider === model.provider && option.name === model.name)) {
118
+ throw new Error('Unsupported Voice model');
119
+ }
120
+ }
121
+ export const VOICE_LOCAL_PROJECTION_VERSION = 'voice-free-form-v1';
122
+ export const voiceProjectionInputSchema = z.strictObject({
123
+ systemPrompt: z.string().min(1).max(100_000),
124
+ model: z.strictObject({ provider: voiceIdSchema, name: voiceIdSchema }),
125
+ voice: voiceDeclarationSchema,
126
+ });
127
+ export function projectVoiceAuthoring(input) {
128
+ const captured = voiceProjectionInputSchema.parse(input);
129
+ const projection = { compilerVersion: VOICE_LOCAL_PROJECTION_VERSION, ...captured };
130
+ return { ...projection, digest: createHash('sha256').update('sequence-voice-local-projection-v1\0')
131
+ .update(canonicalJson(projection)).digest('hex') };
132
+ }
@@ -0,0 +1,247 @@
1
+ import { z } from 'zod';
2
+ export declare const voiceCallSubjectSchema: z.ZodObject<{
3
+ tenantId: z.ZodString;
4
+ environmentId: z.ZodString;
5
+ agentId: z.ZodString;
6
+ sessionId: z.ZodString;
7
+ releaseId: z.ZodString;
8
+ }, z.core.$strict>;
9
+ export type VoiceCallSubject = z.infer<typeof voiceCallSubjectSchema>;
10
+ export declare const voiceResourceReferenceSchema: z.ZodObject<{
11
+ kind: z.ZodString;
12
+ id: z.ZodString;
13
+ }, z.core.$strict>;
14
+ export type VoiceResourceReference = z.infer<typeof voiceResourceReferenceSchema>;
15
+ export declare function sameVoiceResource({ left, right }: {
16
+ left: VoiceResourceReference;
17
+ right: VoiceResourceReference;
18
+ }): boolean;
19
+ export declare const voiceToolOperationRequirementSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ authority: z.ZodLiteral<"public">;
21
+ effect: z.ZodLiteral<"pure_input_computation">;
22
+ }, z.core.$strict>, z.ZodObject<{
23
+ authority: z.ZodLiteral<"public">;
24
+ effect: z.ZodLiteral<"unverified_write">;
25
+ }, z.core.$strict>, z.ZodObject<{
26
+ authority: z.ZodLiteral<"authentication">;
27
+ effect: z.ZodLiteral<"resource_verification">;
28
+ resourceKind: z.ZodString;
29
+ }, z.core.$strict>, z.ZodObject<{
30
+ authority: z.ZodLiteral<"protected">;
31
+ effect: z.ZodEnum<{
32
+ resource_read: "resource_read";
33
+ resource_write: "resource_write";
34
+ }>;
35
+ resourceKind: z.ZodString;
36
+ }, z.core.$strict>], "effect">;
37
+ export type VoiceToolOperationRequirement = z.infer<typeof voiceToolOperationRequirementSchema>;
38
+ export declare function resolveVoiceToolOperationRequirement({ requirement, }: {
39
+ requirement: VoiceToolOperationRequirement | undefined;
40
+ }): VoiceToolOperationRequirement;
41
+ export declare const voiceToolBindingSchema: z.ZodObject<{
42
+ toolAlias: z.ZodString;
43
+ operation: z.ZodString;
44
+ managedFunctionId: z.ZodString;
45
+ functionVersionId: z.ZodString;
46
+ sourceHash: z.ZodString;
47
+ manifestHash: z.ZodString;
48
+ dataBinding: z.ZodObject<{
49
+ attachedIdentityId: z.ZodString;
50
+ dataScopeHash: z.ZodString;
51
+ }, z.core.$strict>;
52
+ runtimeBinding: z.ZodObject<{
53
+ runtimeAccountId: z.ZodString;
54
+ permissionHash: z.ZodString;
55
+ }, z.core.$strict>;
56
+ }, z.core.$strict>;
57
+ export type VoiceToolBinding = z.infer<typeof voiceToolBindingSchema>;
58
+ export declare const voicePublicationToolReviewSchema: z.ZodObject<{
59
+ reviewId: z.ZodString;
60
+ releaseId: z.ZodString;
61
+ scope: z.ZodObject<{
62
+ tenantId: z.ZodString;
63
+ environmentId: z.ZodString;
64
+ agentId: z.ZodString;
65
+ }, z.core.$strict>;
66
+ reviewKind: z.ZodEnum<{
67
+ performed: "performed";
68
+ reused: "reused";
69
+ }>;
70
+ reusedFromReviewId: z.ZodNullable<z.ZodString>;
71
+ reviewerPrincipalId: z.ZodString;
72
+ reviewedAt: z.ZodISODateTime;
73
+ syntheticOnlyConfirmed: z.ZodLiteral<true>;
74
+ requirement: z.ZodDiscriminatedUnion<[z.ZodObject<{
75
+ authority: z.ZodLiteral<"public">;
76
+ effect: z.ZodLiteral<"pure_input_computation">;
77
+ }, z.core.$strict>, z.ZodObject<{
78
+ authority: z.ZodLiteral<"public">;
79
+ effect: z.ZodLiteral<"unverified_write">;
80
+ }, z.core.$strict>, z.ZodObject<{
81
+ authority: z.ZodLiteral<"authentication">;
82
+ effect: z.ZodLiteral<"resource_verification">;
83
+ resourceKind: z.ZodString;
84
+ }, z.core.$strict>, z.ZodObject<{
85
+ authority: z.ZodLiteral<"protected">;
86
+ effect: z.ZodEnum<{
87
+ resource_read: "resource_read";
88
+ resource_write: "resource_write";
89
+ }>;
90
+ resourceKind: z.ZodString;
91
+ }, z.core.$strict>], "effect">;
92
+ binding: z.ZodObject<{
93
+ toolAlias: z.ZodString;
94
+ operation: z.ZodString;
95
+ managedFunctionId: z.ZodString;
96
+ functionVersionId: z.ZodString;
97
+ sourceHash: z.ZodString;
98
+ manifestHash: z.ZodString;
99
+ dataBinding: z.ZodObject<{
100
+ attachedIdentityId: z.ZodString;
101
+ dataScopeHash: z.ZodString;
102
+ }, z.core.$strict>;
103
+ runtimeBinding: z.ZodObject<{
104
+ runtimeAccountId: z.ZodString;
105
+ permissionHash: z.ZodString;
106
+ }, z.core.$strict>;
107
+ }, z.core.$strict>;
108
+ }, z.core.$strict>;
109
+ export type VoicePublicationToolReview = z.infer<typeof voicePublicationToolReviewSchema>;
110
+ export declare function isVoicePublicationToolReviewCurrent({ review, currentBinding, currentRequirement, }: {
111
+ review: VoicePublicationToolReview;
112
+ currentBinding: VoiceToolBinding;
113
+ currentRequirement: VoiceToolOperationRequirement;
114
+ }): boolean;
115
+ export declare const voiceVerificationStatusSchema: z.ZodEnum<{
116
+ unverified: "unverified";
117
+ verified: "verified";
118
+ locked: "locked";
119
+ expired: "expired";
120
+ revoked: "revoked";
121
+ }>;
122
+ export type VoiceVerificationStatus = z.infer<typeof voiceVerificationStatusSchema>;
123
+ export declare const voiceVerificationStateSchema: z.ZodObject<{
124
+ subject: z.ZodObject<{
125
+ tenantId: z.ZodString;
126
+ environmentId: z.ZodString;
127
+ agentId: z.ZodString;
128
+ sessionId: z.ZodString;
129
+ releaseId: z.ZodString;
130
+ }, z.core.$strict>;
131
+ status: z.ZodEnum<{
132
+ unverified: "unverified";
133
+ verified: "verified";
134
+ locked: "locked";
135
+ expired: "expired";
136
+ revoked: "revoked";
137
+ }>;
138
+ attemptBudget: z.ZodObject<{
139
+ maxAttempts: z.ZodNumber;
140
+ usedAttempts: z.ZodNumber;
141
+ }, z.core.$strict>;
142
+ verifiedResource: z.ZodNullable<z.ZodObject<{
143
+ kind: z.ZodString;
144
+ id: z.ZodString;
145
+ }, z.core.$strict>>;
146
+ verificationId: z.ZodNullable<z.ZodString>;
147
+ verificationMethodKey: z.ZodNullable<z.ZodString>;
148
+ verificationExpiresAt: z.ZodNullable<z.ZodISODateTime>;
149
+ authorityExpiresAt: z.ZodISODateTime;
150
+ revision: z.ZodNumber;
151
+ }, z.core.$strict>;
152
+ export type VoiceVerificationState = z.infer<typeof voiceVerificationStateSchema>;
153
+ export declare const voiceVerificationAttemptRequestSchema: z.ZodObject<{
154
+ attemptId: z.ZodString;
155
+ subject: z.ZodObject<{
156
+ tenantId: z.ZodString;
157
+ environmentId: z.ZodString;
158
+ agentId: z.ZodString;
159
+ sessionId: z.ZodString;
160
+ releaseId: z.ZodString;
161
+ }, z.core.$strict>;
162
+ candidateResource: z.ZodObject<{
163
+ kind: z.ZodString;
164
+ id: z.ZodString;
165
+ }, z.core.$strict>;
166
+ methodKey: z.ZodString;
167
+ idempotencyKey: z.ZodString;
168
+ requestDigest: z.ZodString;
169
+ attemptedAt: z.ZodISODateTime;
170
+ }, z.core.$strict>;
171
+ export type VoiceVerificationAttemptRequest = z.infer<typeof voiceVerificationAttemptRequestSchema>;
172
+ export declare const voiceVerificationAttemptSchema: z.ZodObject<{
173
+ attemptId: z.ZodString;
174
+ subject: z.ZodObject<{
175
+ tenantId: z.ZodString;
176
+ environmentId: z.ZodString;
177
+ agentId: z.ZodString;
178
+ sessionId: z.ZodString;
179
+ releaseId: z.ZodString;
180
+ }, z.core.$strict>;
181
+ candidateResource: z.ZodObject<{
182
+ kind: z.ZodString;
183
+ id: z.ZodString;
184
+ }, z.core.$strict>;
185
+ methodKey: z.ZodString;
186
+ idempotencyKey: z.ZodString;
187
+ requestDigest: z.ZodString;
188
+ attemptedAt: z.ZodISODateTime;
189
+ attemptNumber: z.ZodNumber;
190
+ status: z.ZodEnum<{
191
+ verified: "verified";
192
+ pending: "pending";
193
+ rejected: "rejected";
194
+ uncertain: "uncertain";
195
+ }>;
196
+ completedAt: z.ZodNullable<z.ZodISODateTime>;
197
+ verifierInvocationId: z.ZodNullable<z.ZodString>;
198
+ verificationId: z.ZodNullable<z.ZodString>;
199
+ }, z.core.$strict>;
200
+ export type VoiceVerificationAttempt = z.infer<typeof voiceVerificationAttemptSchema>;
201
+ export declare const voiceTrustedVerifierResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
202
+ verificationExpiresAt: z.ZodISODateTime;
203
+ verificationId: z.ZodString;
204
+ attemptId: z.ZodString;
205
+ subject: z.ZodObject<{
206
+ tenantId: z.ZodString;
207
+ environmentId: z.ZodString;
208
+ agentId: z.ZodString;
209
+ sessionId: z.ZodString;
210
+ releaseId: z.ZodString;
211
+ }, z.core.$strict>;
212
+ candidateResource: z.ZodObject<{
213
+ kind: z.ZodString;
214
+ id: z.ZodString;
215
+ }, z.core.$strict>;
216
+ methodKey: z.ZodString;
217
+ idempotencyKey: z.ZodString;
218
+ requestDigest: z.ZodString;
219
+ verifierReviewId: z.ZodString;
220
+ verifierInvocationId: z.ZodString;
221
+ observedFunctionVersionId: z.ZodString;
222
+ completedAt: z.ZodISODateTime;
223
+ verdict: z.ZodLiteral<"verified">;
224
+ }, z.core.$strict>, z.ZodObject<{
225
+ verificationId: z.ZodString;
226
+ attemptId: z.ZodString;
227
+ subject: z.ZodObject<{
228
+ tenantId: z.ZodString;
229
+ environmentId: z.ZodString;
230
+ agentId: z.ZodString;
231
+ sessionId: z.ZodString;
232
+ releaseId: z.ZodString;
233
+ }, z.core.$strict>;
234
+ candidateResource: z.ZodObject<{
235
+ kind: z.ZodString;
236
+ id: z.ZodString;
237
+ }, z.core.$strict>;
238
+ methodKey: z.ZodString;
239
+ idempotencyKey: z.ZodString;
240
+ requestDigest: z.ZodString;
241
+ verifierReviewId: z.ZodString;
242
+ verifierInvocationId: z.ZodString;
243
+ observedFunctionVersionId: z.ZodString;
244
+ completedAt: z.ZodISODateTime;
245
+ verdict: z.ZodLiteral<"rejected">;
246
+ }, z.core.$strict>], "verdict">;
247
+ export type VoiceTrustedVerifierResult = z.infer<typeof voiceTrustedVerifierResultSchema>;
@@ -0,0 +1,177 @@
1
+ import { z } from 'zod';
2
+ import { voiceAgentScopeSchema, voiceHashSchema, voiceIdSchema, voiceLocalKeySchema, voiceRevisionSchema, voiceTimestampSchema, } from './voice-common.js';
3
+ export const voiceCallSubjectSchema = voiceAgentScopeSchema.extend({
4
+ sessionId: voiceIdSchema,
5
+ releaseId: voiceIdSchema,
6
+ });
7
+ export const voiceResourceReferenceSchema = z.strictObject({
8
+ kind: voiceLocalKeySchema,
9
+ id: voiceIdSchema,
10
+ });
11
+ export function sameVoiceResource({ left, right }) {
12
+ return left.kind === right.kind && left.id === right.id;
13
+ }
14
+ const publicPureOperationSchema = z.strictObject({
15
+ authority: z.literal('public'),
16
+ effect: z.literal('pure_input_computation'),
17
+ });
18
+ const publicUnverifiedWriteOperationSchema = z.strictObject({
19
+ authority: z.literal('public'),
20
+ effect: z.literal('unverified_write'),
21
+ });
22
+ const authenticationOperationSchema = z.strictObject({
23
+ authority: z.literal('authentication'),
24
+ effect: z.literal('resource_verification'),
25
+ resourceKind: voiceLocalKeySchema,
26
+ });
27
+ const protectedOperationSchema = z.strictObject({
28
+ authority: z.literal('protected'),
29
+ effect: z.enum(['resource_read', 'resource_write']),
30
+ resourceKind: voiceLocalKeySchema,
31
+ });
32
+ export const voiceToolOperationRequirementSchema = z.discriminatedUnion('effect', [
33
+ publicPureOperationSchema,
34
+ publicUnverifiedWriteOperationSchema,
35
+ authenticationOperationSchema,
36
+ protectedOperationSchema,
37
+ ]);
38
+ export function resolveVoiceToolOperationRequirement({ requirement, }) {
39
+ return voiceToolOperationRequirementSchema.parse(requirement);
40
+ }
41
+ export const voiceToolBindingSchema = z.strictObject({
42
+ toolAlias: voiceLocalKeySchema,
43
+ operation: voiceLocalKeySchema,
44
+ managedFunctionId: voiceIdSchema,
45
+ functionVersionId: voiceIdSchema,
46
+ sourceHash: voiceHashSchema,
47
+ manifestHash: voiceHashSchema,
48
+ dataBinding: z.strictObject({
49
+ attachedIdentityId: voiceIdSchema,
50
+ dataScopeHash: voiceHashSchema,
51
+ }),
52
+ runtimeBinding: z.strictObject({
53
+ runtimeAccountId: voiceIdSchema,
54
+ permissionHash: voiceHashSchema,
55
+ }),
56
+ });
57
+ export const voicePublicationToolReviewSchema = z
58
+ .strictObject({
59
+ reviewId: voiceIdSchema,
60
+ releaseId: voiceIdSchema,
61
+ scope: voiceAgentScopeSchema,
62
+ reviewKind: z.enum(['performed', 'reused']),
63
+ reusedFromReviewId: voiceIdSchema.nullable(),
64
+ reviewerPrincipalId: voiceIdSchema,
65
+ reviewedAt: voiceTimestampSchema,
66
+ syntheticOnlyConfirmed: z.literal(true),
67
+ requirement: voiceToolOperationRequirementSchema,
68
+ binding: voiceToolBindingSchema,
69
+ })
70
+ .superRefine((review, context) => {
71
+ if (review.reviewKind === 'performed' && review.reusedFromReviewId !== null) {
72
+ context.addIssue({
73
+ code: 'custom', path: ['reusedFromReviewId'],
74
+ message: 'a performed review cannot reuse another review',
75
+ });
76
+ }
77
+ if (review.reviewKind === 'reused' && review.reusedFromReviewId === null) {
78
+ context.addIssue({
79
+ code: 'custom', path: ['reusedFromReviewId'],
80
+ message: 'a reused review must identify its source review',
81
+ });
82
+ }
83
+ });
84
+ function sameToolBinding({ left, right }) {
85
+ return left.toolAlias === right.toolAlias &&
86
+ left.operation === right.operation &&
87
+ left.managedFunctionId === right.managedFunctionId &&
88
+ left.functionVersionId === right.functionVersionId &&
89
+ left.sourceHash === right.sourceHash &&
90
+ left.manifestHash === right.manifestHash &&
91
+ left.dataBinding.attachedIdentityId === right.dataBinding.attachedIdentityId &&
92
+ left.dataBinding.dataScopeHash === right.dataBinding.dataScopeHash &&
93
+ left.runtimeBinding.runtimeAccountId === right.runtimeBinding.runtimeAccountId &&
94
+ left.runtimeBinding.permissionHash === right.runtimeBinding.permissionHash;
95
+ }
96
+ export function isVoicePublicationToolReviewCurrent({ review, currentBinding, currentRequirement, }) {
97
+ const parsedReview = voicePublicationToolReviewSchema.parse(review);
98
+ const parsedBinding = voiceToolBindingSchema.parse(currentBinding);
99
+ const parsedRequirement = voiceToolOperationRequirementSchema.parse(currentRequirement);
100
+ return sameToolBinding({ left: parsedReview.binding, right: parsedBinding }) &&
101
+ parsedReview.requirement.authority === parsedRequirement.authority &&
102
+ parsedReview.requirement.effect === parsedRequirement.effect &&
103
+ (parsedReview.requirement.authority === 'public' || (parsedRequirement.authority !== 'public' &&
104
+ parsedReview.requirement.resourceKind === parsedRequirement.resourceKind));
105
+ }
106
+ export const voiceVerificationStatusSchema = z.enum([
107
+ 'unverified', 'verified', 'locked', 'expired', 'revoked',
108
+ ]);
109
+ export const voiceVerificationStateSchema = z
110
+ .strictObject({
111
+ subject: voiceCallSubjectSchema,
112
+ status: voiceVerificationStatusSchema,
113
+ attemptBudget: z.strictObject({
114
+ maxAttempts: z.number().int().positive().max(100).safe(),
115
+ usedAttempts: z.number().int().nonnegative().max(100).safe(),
116
+ }),
117
+ verifiedResource: voiceResourceReferenceSchema.nullable(),
118
+ verificationId: voiceIdSchema.nullable(),
119
+ verificationMethodKey: voiceLocalKeySchema.nullable(),
120
+ verificationExpiresAt: voiceTimestampSchema.nullable(),
121
+ authorityExpiresAt: voiceTimestampSchema,
122
+ revision: voiceRevisionSchema,
123
+ })
124
+ .superRefine((state, context) => {
125
+ if (state.attemptBudget.usedAttempts > state.attemptBudget.maxAttempts) {
126
+ context.addIssue({
127
+ code: 'custom', path: ['attemptBudget', 'usedAttempts'],
128
+ message: 'used verification attempts cannot exceed the shared budget',
129
+ });
130
+ }
131
+ const evidence = [state.verifiedResource, state.verificationId,
132
+ state.verificationMethodKey, state.verificationExpiresAt];
133
+ const incompleteVerified = state.status === 'verified' && evidence.some((value) => value === null);
134
+ const authorityOnInactive = state.status !== 'verified' && evidence.some((value) => value !== null);
135
+ if (incompleteVerified || authorityOnInactive) {
136
+ context.addIssue({
137
+ code: 'custom', path: ['status'],
138
+ message: 'only verified state may retain complete resource authority evidence',
139
+ });
140
+ }
141
+ });
142
+ export const voiceVerificationAttemptRequestSchema = z.strictObject({
143
+ attemptId: voiceIdSchema,
144
+ subject: voiceCallSubjectSchema,
145
+ candidateResource: voiceResourceReferenceSchema,
146
+ methodKey: voiceLocalKeySchema,
147
+ idempotencyKey: voiceIdSchema,
148
+ requestDigest: voiceHashSchema,
149
+ attemptedAt: voiceTimestampSchema,
150
+ });
151
+ export const voiceVerificationAttemptSchema = voiceVerificationAttemptRequestSchema.extend({
152
+ attemptNumber: z.number().int().positive().safe(),
153
+ status: z.enum(['pending', 'verified', 'rejected', 'uncertain']),
154
+ completedAt: voiceTimestampSchema.nullable(),
155
+ verifierInvocationId: voiceIdSchema.nullable(),
156
+ verificationId: voiceIdSchema.nullable(),
157
+ });
158
+ const verifierResultBase = {
159
+ verificationId: voiceIdSchema,
160
+ attemptId: voiceIdSchema,
161
+ subject: voiceCallSubjectSchema,
162
+ candidateResource: voiceResourceReferenceSchema,
163
+ methodKey: voiceLocalKeySchema,
164
+ idempotencyKey: voiceIdSchema,
165
+ requestDigest: voiceHashSchema,
166
+ verifierReviewId: voiceIdSchema,
167
+ verifierInvocationId: voiceIdSchema,
168
+ observedFunctionVersionId: voiceIdSchema,
169
+ completedAt: voiceTimestampSchema,
170
+ };
171
+ export const voiceTrustedVerifierResultSchema = z.discriminatedUnion('verdict', [
172
+ z.strictObject({
173
+ verdict: z.literal('verified'), ...verifierResultBase,
174
+ verificationExpiresAt: voiceTimestampSchema,
175
+ }),
176
+ z.strictObject({ verdict: z.literal('rejected'), ...verifierResultBase }),
177
+ ]);
@@ -0,0 +1,29 @@
1
+ import { type VoiceCallSubject, type VoicePublicationToolReview, type VoiceToolBinding, type VoiceToolOperationRequirement, type VoiceVerificationState, type VoiceResourceReference } from './voice-authority-contracts.js';
2
+ export type VoiceAuthoritySubject = {
3
+ kind: 'public';
4
+ } | {
5
+ kind: 'authentication';
6
+ } | {
7
+ kind: 'unverified';
8
+ } | {
9
+ kind: 'verified_resource';
10
+ resource: VoiceResourceReference;
11
+ verificationId: string;
12
+ };
13
+ type AuthorityDenial = 'resource_verification_expired' | 'resource_verification_required' | 'invalid_verification_binding' | 'publication_review_required' | 'verification_locked' | 'verification_revoked';
14
+ export type VoiceToolAuthorityDecision = {
15
+ allowed: true;
16
+ authoritySubject: VoiceAuthoritySubject;
17
+ } | {
18
+ allowed: false;
19
+ reason: AuthorityDenial;
20
+ };
21
+ export declare function evaluateVoiceToolAuthority({ requirement, subject, verification, publicationReview, currentBinding, now, }: {
22
+ requirement: VoiceToolOperationRequirement | undefined;
23
+ subject: VoiceCallSubject;
24
+ verification: VoiceVerificationState | null;
25
+ publicationReview: VoicePublicationToolReview | null;
26
+ currentBinding: VoiceToolBinding | null;
27
+ now: string;
28
+ }): VoiceToolAuthorityDecision;
29
+ export {};
@@ -0,0 +1,80 @@
1
+ import { voiceTimestampSchema } from './voice-common.js';
2
+ import { isVoicePublicationToolReviewCurrent, resolveVoiceToolOperationRequirement, voiceCallSubjectSchema, voicePublicationToolReviewSchema, voiceVerificationStateSchema, } from './voice-authority-contracts.js';
3
+ function sameSubject({ left, right }) {
4
+ return left.tenantId === right.tenantId &&
5
+ left.environmentId === right.environmentId &&
6
+ left.agentId === right.agentId &&
7
+ left.sessionId === right.sessionId &&
8
+ left.releaseId === right.releaseId;
9
+ }
10
+ function reviewMatchesOperation({ review, binding, requirement, subject }) {
11
+ return review.releaseId === subject.releaseId &&
12
+ review.scope.tenantId === subject.tenantId &&
13
+ review.scope.environmentId === subject.environmentId &&
14
+ review.scope.agentId === subject.agentId &&
15
+ isVoicePublicationToolReviewCurrent({
16
+ review, currentBinding: binding, currentRequirement: requirement,
17
+ });
18
+ }
19
+ function inactiveVerificationDecision({ state, now }) {
20
+ if (state.status === 'revoked') {
21
+ return { allowed: false, reason: 'verification_revoked' };
22
+ }
23
+ if (state.status === 'locked') {
24
+ return { allowed: false, reason: 'verification_locked' };
25
+ }
26
+ const expired = state.status === 'expired' ||
27
+ Date.parse(now) >= Date.parse(state.authorityExpiresAt);
28
+ return expired ? { allowed: false, reason: 'resource_verification_expired' } : null;
29
+ }
30
+ export function evaluateVoiceToolAuthority({ requirement, subject, verification, publicationReview, currentBinding, now, }) {
31
+ if (requirement === undefined)
32
+ return { allowed: false, reason: 'publication_review_required' };
33
+ const policy = resolveVoiceToolOperationRequirement({ requirement });
34
+ const call = voiceCallSubjectSchema.parse(subject);
35
+ const parsedNow = voiceTimestampSchema.parse(now);
36
+ if (publicationReview === null || currentBinding === null) {
37
+ return { allowed: false, reason: 'publication_review_required' };
38
+ }
39
+ const review = voicePublicationToolReviewSchema.parse(publicationReview);
40
+ if (!reviewMatchesOperation({ review, binding: currentBinding, requirement: policy,
41
+ subject: call })) {
42
+ return { allowed: false, reason: 'publication_review_required' };
43
+ }
44
+ if (policy.authority === 'public') {
45
+ const kind = policy.effect === 'unverified_write'
46
+ ? 'unverified'
47
+ : 'public';
48
+ return { allowed: true, authoritySubject: { kind } };
49
+ }
50
+ if (verification === null) {
51
+ return policy.authority === 'authentication'
52
+ ? { allowed: true, authoritySubject: { kind: 'authentication' } }
53
+ : { allowed: false, reason: 'resource_verification_required' };
54
+ }
55
+ const state = voiceVerificationStateSchema.parse(verification);
56
+ if (!sameSubject({ left: call, right: state.subject })) {
57
+ return { allowed: false, reason: 'invalid_verification_binding' };
58
+ }
59
+ const inactive = inactiveVerificationDecision({ state, now: parsedNow });
60
+ if (inactive !== null)
61
+ return inactive;
62
+ if (policy.authority === 'authentication') {
63
+ return { allowed: true, authoritySubject: { kind: 'authentication' } };
64
+ }
65
+ if (state.status !== 'verified' || state.verifiedResource === null ||
66
+ state.verifiedResource.kind !== policy.resourceKind ||
67
+ state.verificationId === null || state.verificationExpiresAt === null) {
68
+ return { allowed: false, reason: 'resource_verification_required' };
69
+ }
70
+ if (Date.parse(parsedNow) >= Date.parse(state.verificationExpiresAt)) {
71
+ return { allowed: false, reason: 'resource_verification_expired' };
72
+ }
73
+ return {
74
+ allowed: true,
75
+ authoritySubject: {
76
+ kind: 'verified_resource', resource: state.verifiedResource,
77
+ verificationId: state.verificationId,
78
+ },
79
+ };
80
+ }