@canonmsg/backend-contracts 2.3.0 → 4.0.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.
@@ -67,6 +67,12 @@ export declare const VERB_ID_PATTERNS: {
67
67
  readonly actionId: "^[A-Za-z0-9_.:-]{1,80}$";
68
68
  readonly questionId: "^[A-Za-z0-9_.:-]{1,120}$";
69
69
  readonly sessionRuleToolPattern: "^[\\w.*:-]{1,128}$";
70
+ readonly runtimeCorrelationValue: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
71
+ readonly runtimeMethod: "^[A-Za-z0-9_][A-Za-z0-9_./:\\-]{0,255}$";
72
+ readonly runtimeOptionValue: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
73
+ readonly workspaceOptionId: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
74
+ readonly runtimeHandleKey: "^[A-Za-z0-9_.:-]{1,80}$";
75
+ readonly runtimeControlId: "^[A-Za-z0-9_-]{1,80}$";
70
76
  };
71
77
  /**
72
78
  * Server-enforced limits, single-sourced. Each value cites its enforcement
@@ -134,6 +140,9 @@ export declare const VERB_LIMITS: {
134
140
  readonly nativeKeys: 24;
135
141
  readonly nativeValueChars: 256;
136
142
  readonly nativeHandles: 16;
143
+ /** Initial agent-session setup carried by send_to. */
144
+ readonly sessionConfigValues: 24;
145
+ readonly sessionConfigValueChars: 256;
137
146
  /** Deadlines (functions/src/utils/runtimeRequestHelpers.ts). */
138
147
  readonly minTimeoutMs: 1000;
139
148
  /** input/card/plan ceiling (30 minutes). */
@@ -181,6 +190,50 @@ export type VerbSessionSelection = {
181
190
  mode: 'specific';
182
191
  conversationId: string;
183
192
  };
193
+ /**
194
+ * Public setup policy for the target agent session. Every value is a stable
195
+ * runtime-advertised option id, never a label, prompt, path, or other free
196
+ * text. The server also validates each selection against the target's live
197
+ * descriptor before creating a session.
198
+ */
199
+ export interface VerbSessionConfig {
200
+ model?: string;
201
+ permissionMode?: string;
202
+ effort?: string;
203
+ runtimeControlValues?: Record<string, string>;
204
+ workspaceId?: string;
205
+ executionMode?: 'worktree' | 'locked';
206
+ }
207
+ /**
208
+ * Bounded runtime correlation carried in the public wire envelope. These are
209
+ * opaque identifiers only; workspace paths, commands, prompts, summaries,
210
+ * and model labels belong in encrypted content or owner-local runtime state.
211
+ */
212
+ export interface VerbNativeMetadata {
213
+ runtime?: string;
214
+ method?: string;
215
+ requestId?: string;
216
+ provider?: string;
217
+ origin?: string;
218
+ surface?: string;
219
+ threadId?: string;
220
+ turnId?: string;
221
+ runId?: string;
222
+ itemId?: string;
223
+ toolCallId?: string;
224
+ approvalId?: string;
225
+ pluginId?: string;
226
+ sessionKey?: string;
227
+ nodeId?: string;
228
+ handles?: Record<string, string>;
229
+ }
230
+ export declare const VERB_NATIVE_METADATA_KEYS: readonly ["runtime", "method", "requestId", "provider", "origin", "surface", "threadId", "turnId", "runId", "itemId", "toolCallId", "approvalId", "pluginId", "sessionKey", "nodeId", "handles"];
231
+ /**
232
+ * Keep only the typed, content-free runtime correlation contract. Invalid or
233
+ * unknown fields are omitted on compatibility REST paths; canon.verb-wire.v1
234
+ * rejects the same fields through its strict JSON Schema.
235
+ */
236
+ export declare function normalizeVerbNativeMetadata(value: unknown): VerbNativeMetadata | undefined;
184
237
  export interface VerbMediaAttachment {
185
238
  kind: 'image' | 'audio' | 'video' | 'file';
186
239
  /** Must come from /media/upload (Canon storage) or the GIF picker — server allowlisted. */
@@ -242,7 +295,7 @@ export interface SendToInput {
242
295
  /** Only meaningful for user targets that are agents. Default: continue_or_create. */
243
296
  sessionSelection?: VerbSessionSelection;
244
297
  /** Coding-agent session setup; only applied when the target is an agent. */
245
- sessionConfig?: Record<string, unknown> | null;
298
+ sessionConfig?: VerbSessionConfig | null;
246
299
  messageOptions?: VerbMessageOptions;
247
300
  }
248
301
  export type SendToResult = {
@@ -308,7 +361,7 @@ export interface RequestInputInput {
308
361
  secretName?: string;
309
362
  sensitive?: boolean;
310
363
  responseUserId?: string;
311
- native?: Record<string, unknown>;
364
+ native?: VerbNativeMetadata;
312
365
  turnId?: string;
313
366
  /** Relative deadline; server ceiling is VERB_LIMITS.maxTimeoutMs (30 min). */
314
367
  timeoutMs?: number;
@@ -376,7 +429,7 @@ export interface RequestApprovalInput {
376
429
  category?: VerbApprovalCategory;
377
430
  details?: VerbApprovalDetail[];
378
431
  diff?: VerbUnifiedDiff;
379
- native?: Record<string, unknown>;
432
+ native?: VerbNativeMetadata;
380
433
  runtimeId?: string;
381
434
  turnId?: string;
382
435
  responseUserId?: string;
@@ -455,7 +508,7 @@ export interface SendCardInput {
455
508
  conversationId?: string;
456
509
  card: VerbRuntimeCard;
457
510
  cardId?: string;
458
- native?: Record<string, unknown>;
511
+ native?: VerbNativeMetadata;
459
512
  runtimeId?: string;
460
513
  turnId?: string;
461
514
  }
@@ -719,6 +772,9 @@ export declare const CANON_VERB_LIMITS_ARTIFACT: {
719
772
  readonly nativeKeys: 24;
720
773
  readonly nativeValueChars: 256;
721
774
  readonly nativeHandles: 16;
775
+ /** Initial agent-session setup carried by send_to. */
776
+ readonly sessionConfigValues: 24;
777
+ readonly sessionConfigValueChars: 256;
722
778
  /** Deadlines (functions/src/utils/runtimeRequestHelpers.ts). */
723
779
  readonly minTimeoutMs: 1000;
724
780
  /** input/card/plan ceiling (30 minutes). */
@@ -746,6 +802,12 @@ export declare const CANON_VERB_LIMITS_ARTIFACT: {
746
802
  readonly actionId: "^[A-Za-z0-9_.:-]{1,80}$";
747
803
  readonly questionId: "^[A-Za-z0-9_.:-]{1,120}$";
748
804
  readonly sessionRuleToolPattern: "^[\\w.*:-]{1,128}$";
805
+ readonly runtimeCorrelationValue: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
806
+ readonly runtimeMethod: "^[A-Za-z0-9_][A-Za-z0-9_./:\\-]{0,255}$";
807
+ readonly runtimeOptionValue: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
808
+ readonly workspaceOptionId: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
809
+ readonly runtimeHandleKey: "^[A-Za-z0-9_.:-]{1,80}$";
810
+ readonly runtimeControlId: "^[A-Za-z0-9_-]{1,80}$";
749
811
  };
750
812
  readonly byteSemantics: {
751
813
  readonly 'send_to.text': "utf8_bytes<=messageTextBytes";
@@ -67,6 +67,12 @@ export const VERB_ID_PATTERNS = {
67
67
  actionId: '^[A-Za-z0-9_.:-]{1,80}$',
68
68
  questionId: '^[A-Za-z0-9_.:-]{1,120}$',
69
69
  sessionRuleToolPattern: '^[\\w.*:-]{1,128}$',
70
+ runtimeCorrelationValue: '^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$',
71
+ runtimeMethod: '^[A-Za-z0-9_][A-Za-z0-9_./:\\-]{0,255}$',
72
+ runtimeOptionValue: '^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$',
73
+ workspaceOptionId: '^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$',
74
+ runtimeHandleKey: '^[A-Za-z0-9_.:-]{1,80}$',
75
+ runtimeControlId: '^[A-Za-z0-9_-]{1,80}$',
70
76
  };
71
77
  /**
72
78
  * Server-enforced limits, single-sourced. Each value cites its enforcement
@@ -134,6 +140,9 @@ export const VERB_LIMITS = {
134
140
  nativeKeys: 24,
135
141
  nativeValueChars: 256,
136
142
  nativeHandles: 16,
143
+ /** Initial agent-session setup carried by send_to. */
144
+ sessionConfigValues: 24,
145
+ sessionConfigValueChars: 256,
137
146
  /** Deadlines (functions/src/utils/runtimeRequestHelpers.ts). */
138
147
  minTimeoutMs: 1000,
139
148
  /** input/card/plan ceiling (30 minutes). */
@@ -181,6 +190,65 @@ export const CANON_VERB_NAMES = [
181
190
  'list_contact_requests',
182
191
  'list_conversations',
183
192
  ];
193
+ export const VERB_NATIVE_METADATA_KEYS = [
194
+ 'runtime',
195
+ 'method',
196
+ 'requestId',
197
+ 'provider',
198
+ 'origin',
199
+ 'surface',
200
+ 'threadId',
201
+ 'turnId',
202
+ 'runId',
203
+ 'itemId',
204
+ 'toolCallId',
205
+ 'approvalId',
206
+ 'pluginId',
207
+ 'sessionKey',
208
+ 'nodeId',
209
+ 'handles',
210
+ ];
211
+ const VERB_NATIVE_STRING_KEYS = VERB_NATIVE_METADATA_KEYS.filter((key) => key !== 'handles');
212
+ const RUNTIME_CORRELATION_VALUE_PATTERN = new RegExp(VERB_ID_PATTERNS.runtimeCorrelationValue);
213
+ const RUNTIME_METHOD_PATTERN = new RegExp(VERB_ID_PATTERNS.runtimeMethod);
214
+ const RUNTIME_HANDLE_KEY_PATTERN = new RegExp(VERB_ID_PATTERNS.runtimeHandleKey);
215
+ function isPlainRecord(value) {
216
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
217
+ }
218
+ /**
219
+ * Keep only the typed, content-free runtime correlation contract. Invalid or
220
+ * unknown fields are omitted on compatibility REST paths; canon.verb-wire.v1
221
+ * rejects the same fields through its strict JSON Schema.
222
+ */
223
+ export function normalizeVerbNativeMetadata(value) {
224
+ if (!isPlainRecord(value))
225
+ return undefined;
226
+ const native = {};
227
+ for (const key of VERB_NATIVE_STRING_KEYS) {
228
+ const raw = value[key];
229
+ if (typeof raw !== 'string')
230
+ continue;
231
+ const normalized = raw.trim();
232
+ const pattern = key === 'method'
233
+ ? RUNTIME_METHOD_PATTERN
234
+ : RUNTIME_CORRELATION_VALUE_PATTERN;
235
+ if (pattern.test(normalized))
236
+ native[key] = normalized;
237
+ }
238
+ if (isPlainRecord(value.handles)) {
239
+ const handles = {};
240
+ for (const [key, raw] of Object.entries(value.handles).slice(0, VERB_LIMITS.nativeHandles)) {
241
+ if (!RUNTIME_HANDLE_KEY_PATTERN.test(key) || typeof raw !== 'string')
242
+ continue;
243
+ const normalized = raw.trim();
244
+ if (RUNTIME_CORRELATION_VALUE_PATTERN.test(normalized))
245
+ handles[key] = normalized;
246
+ }
247
+ if (Object.keys(handles).length > 0)
248
+ native.handles = handles;
249
+ }
250
+ return Object.keys(native).length > 0 ? native : undefined;
251
+ }
184
252
  /**
185
253
  * Error code on the 400 a create_group receives when NO member is directly
186
254
  * addable (approval-required members can only be invited to an existing
@@ -28,6 +28,146 @@
28
28
  * endpoints validate against these schemas directly).
29
29
  */
30
30
  import { type CanonVerbName } from './verbContract.js';
31
+ export declare const VERB_NATIVE_METADATA_JSON_SCHEMA: {
32
+ readonly type: "object";
33
+ readonly description: string;
34
+ readonly maxProperties: 24;
35
+ readonly additionalProperties: false;
36
+ readonly properties: {
37
+ readonly runtime: {
38
+ readonly type: "string";
39
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
40
+ readonly maxLength: 256;
41
+ };
42
+ readonly method: {
43
+ readonly type: "string";
44
+ readonly pattern: "^[A-Za-z0-9_][A-Za-z0-9_./:\\-]{0,255}$";
45
+ readonly maxLength: 256;
46
+ };
47
+ readonly requestId: {
48
+ readonly type: "string";
49
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
50
+ readonly maxLength: 256;
51
+ };
52
+ readonly provider: {
53
+ readonly type: "string";
54
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
55
+ readonly maxLength: 256;
56
+ };
57
+ readonly origin: {
58
+ readonly type: "string";
59
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
60
+ readonly maxLength: 256;
61
+ };
62
+ readonly surface: {
63
+ readonly type: "string";
64
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
65
+ readonly maxLength: 256;
66
+ };
67
+ readonly threadId: {
68
+ readonly type: "string";
69
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
70
+ readonly maxLength: 256;
71
+ };
72
+ readonly turnId: {
73
+ readonly type: "string";
74
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
75
+ readonly maxLength: 256;
76
+ };
77
+ readonly runId: {
78
+ readonly type: "string";
79
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
80
+ readonly maxLength: 256;
81
+ };
82
+ readonly itemId: {
83
+ readonly type: "string";
84
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
85
+ readonly maxLength: 256;
86
+ };
87
+ readonly toolCallId: {
88
+ readonly type: "string";
89
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
90
+ readonly maxLength: 256;
91
+ };
92
+ readonly approvalId: {
93
+ readonly type: "string";
94
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
95
+ readonly maxLength: 256;
96
+ };
97
+ readonly pluginId: {
98
+ readonly type: "string";
99
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
100
+ readonly maxLength: 256;
101
+ };
102
+ readonly sessionKey: {
103
+ readonly type: "string";
104
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
105
+ readonly maxLength: 256;
106
+ };
107
+ readonly nodeId: {
108
+ readonly type: "string";
109
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
110
+ readonly maxLength: 256;
111
+ };
112
+ readonly handles: {
113
+ readonly type: "object";
114
+ readonly maxProperties: 16;
115
+ readonly propertyNames: {
116
+ readonly pattern: "^[A-Za-z0-9_.:-]{1,80}$";
117
+ };
118
+ readonly additionalProperties: {
119
+ readonly type: "string";
120
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
121
+ readonly maxLength: 256;
122
+ };
123
+ };
124
+ };
125
+ };
126
+ export declare const VERB_SESSION_CONFIG_JSON_SCHEMA: {
127
+ readonly type: "object";
128
+ readonly description: string;
129
+ readonly additionalProperties: false;
130
+ readonly properties: {
131
+ readonly model: {
132
+ readonly type: "string";
133
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
134
+ readonly maxLength: 256;
135
+ };
136
+ readonly permissionMode: {
137
+ readonly type: "string";
138
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
139
+ readonly maxLength: 256;
140
+ };
141
+ readonly effort: {
142
+ readonly type: "string";
143
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
144
+ readonly maxLength: 256;
145
+ };
146
+ readonly workspaceId: {
147
+ readonly type: "string";
148
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
149
+ readonly maxLength: 256;
150
+ };
151
+ readonly executionMode: {
152
+ readonly enum: readonly ["worktree", "locked"];
153
+ };
154
+ readonly runtimeControlValues: {
155
+ readonly type: "object";
156
+ readonly maxProperties: 24;
157
+ readonly propertyNames: {
158
+ readonly pattern: "^[A-Za-z0-9_-]{1,80}$";
159
+ readonly not: {
160
+ readonly enum: readonly ["model", "workspace", "executionMode", "permissionMode", "effort", "interrupt", "runtimeControlValues", "updatedAt", "updatedBy"];
161
+ };
162
+ };
163
+ readonly additionalProperties: {
164
+ readonly type: "string";
165
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
166
+ readonly maxLength: 256;
167
+ };
168
+ };
169
+ };
170
+ };
31
171
  export declare const CANON_VERBS_JSON_SCHEMA: {
32
172
  readonly $schema: "https://json-schema.org/draft/2020-12/schema";
33
173
  readonly $id: "https://canonmsg.com/schemas/canon.verbs.v1.json";
@@ -372,7 +512,142 @@ export declare const CANON_VERBS_JSON_SCHEMA: {
372
512
  readonly native: {
373
513
  readonly type: "object";
374
514
  readonly description: string;
375
- readonly additionalProperties: true;
515
+ readonly maxProperties: 24;
516
+ readonly additionalProperties: false;
517
+ readonly properties: {
518
+ readonly runtime: {
519
+ readonly type: "string";
520
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
521
+ readonly maxLength: 256;
522
+ };
523
+ readonly method: {
524
+ readonly type: "string";
525
+ readonly pattern: "^[A-Za-z0-9_][A-Za-z0-9_./:\\-]{0,255}$";
526
+ readonly maxLength: 256;
527
+ };
528
+ readonly requestId: {
529
+ readonly type: "string";
530
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
531
+ readonly maxLength: 256;
532
+ };
533
+ readonly provider: {
534
+ readonly type: "string";
535
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
536
+ readonly maxLength: 256;
537
+ };
538
+ readonly origin: {
539
+ readonly type: "string";
540
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
541
+ readonly maxLength: 256;
542
+ };
543
+ readonly surface: {
544
+ readonly type: "string";
545
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
546
+ readonly maxLength: 256;
547
+ };
548
+ readonly threadId: {
549
+ readonly type: "string";
550
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
551
+ readonly maxLength: 256;
552
+ };
553
+ readonly turnId: {
554
+ readonly type: "string";
555
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
556
+ readonly maxLength: 256;
557
+ };
558
+ readonly runId: {
559
+ readonly type: "string";
560
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
561
+ readonly maxLength: 256;
562
+ };
563
+ readonly itemId: {
564
+ readonly type: "string";
565
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
566
+ readonly maxLength: 256;
567
+ };
568
+ readonly toolCallId: {
569
+ readonly type: "string";
570
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
571
+ readonly maxLength: 256;
572
+ };
573
+ readonly approvalId: {
574
+ readonly type: "string";
575
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
576
+ readonly maxLength: 256;
577
+ };
578
+ readonly pluginId: {
579
+ readonly type: "string";
580
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
581
+ readonly maxLength: 256;
582
+ };
583
+ readonly sessionKey: {
584
+ readonly type: "string";
585
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
586
+ readonly maxLength: 256;
587
+ };
588
+ readonly nodeId: {
589
+ readonly type: "string";
590
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
591
+ readonly maxLength: 256;
592
+ };
593
+ readonly handles: {
594
+ readonly type: "object";
595
+ readonly maxProperties: 16;
596
+ readonly propertyNames: {
597
+ readonly pattern: "^[A-Za-z0-9_.:-]{1,80}$";
598
+ };
599
+ readonly additionalProperties: {
600
+ readonly type: "string";
601
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
602
+ readonly maxLength: 256;
603
+ };
604
+ };
605
+ };
606
+ };
607
+ readonly sessionConfig: {
608
+ readonly type: "object";
609
+ readonly description: string;
610
+ readonly additionalProperties: false;
611
+ readonly properties: {
612
+ readonly model: {
613
+ readonly type: "string";
614
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
615
+ readonly maxLength: 256;
616
+ };
617
+ readonly permissionMode: {
618
+ readonly type: "string";
619
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
620
+ readonly maxLength: 256;
621
+ };
622
+ readonly effort: {
623
+ readonly type: "string";
624
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
625
+ readonly maxLength: 256;
626
+ };
627
+ readonly workspaceId: {
628
+ readonly type: "string";
629
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:@+\\-]{0,255}$";
630
+ readonly maxLength: 256;
631
+ };
632
+ readonly executionMode: {
633
+ readonly enum: readonly ["worktree", "locked"];
634
+ };
635
+ readonly runtimeControlValues: {
636
+ readonly type: "object";
637
+ readonly maxProperties: 24;
638
+ readonly propertyNames: {
639
+ readonly pattern: "^[A-Za-z0-9_-]{1,80}$";
640
+ readonly not: {
641
+ readonly enum: readonly ["model", "workspace", "executionMode", "permissionMode", "effort", "interrupt", "runtimeControlValues", "updatedAt", "updatedBy"];
642
+ };
643
+ };
644
+ readonly additionalProperties: {
645
+ readonly type: "string";
646
+ readonly pattern: "^[A-Za-z0-9@_][A-Za-z0-9_.:/@+\\-]{0,255}$";
647
+ readonly maxLength: 256;
648
+ };
649
+ };
650
+ };
376
651
  };
377
652
  readonly send_to_input: {
378
653
  readonly type: "object";
@@ -413,7 +688,11 @@ export declare const CANON_VERBS_JSON_SCHEMA: {
413
688
  $ref: string;
414
689
  };
415
690
  readonly sessionConfig: {
416
- readonly type: readonly ["object", "null"];
691
+ readonly oneOf: readonly [{
692
+ $ref: string;
693
+ }, {
694
+ readonly type: "null";
695
+ }];
417
696
  readonly description: string;
418
697
  };
419
698
  readonly messageOptions: {
@@ -247,12 +247,89 @@ const runtimeCardDef = {
247
247
  blocks: { type: 'array', minItems: 1, maxItems: VERB_LIMITS.cardServerBlocks },
248
248
  },
249
249
  };
250
- const nativeDef = {
250
+ const runtimeCorrelationValueDef = {
251
+ type: 'string',
252
+ pattern: VERB_ID_PATTERNS.runtimeCorrelationValue,
253
+ maxLength: VERB_LIMITS.nativeValueChars,
254
+ };
255
+ const runtimeMethodDef = {
256
+ type: 'string',
257
+ pattern: VERB_ID_PATTERNS.runtimeMethod,
258
+ maxLength: VERB_LIMITS.nativeValueChars,
259
+ };
260
+ export const VERB_NATIVE_METADATA_JSON_SCHEMA = {
251
261
  type: 'object',
252
- description: `Runtime correlation handles (<= ${VERB_LIMITS.nativeKeys} keys, string values <= `
253
- + `${VERB_LIMITS.nativeValueChars} chars or a nested handles map <= ${VERB_LIMITS.nativeHandles}; `
254
- + 'functions/src/api/interactionKinds.ts normalizeNative).',
255
- additionalProperties: true,
262
+ description: 'Content-free runtime correlation ids. Commands, paths, prompts, summaries, '
263
+ + 'and model labels are not permitted in this public envelope.',
264
+ maxProperties: VERB_LIMITS.nativeKeys,
265
+ additionalProperties: false,
266
+ properties: {
267
+ runtime: runtimeCorrelationValueDef,
268
+ method: runtimeMethodDef,
269
+ requestId: runtimeCorrelationValueDef,
270
+ provider: runtimeCorrelationValueDef,
271
+ origin: runtimeCorrelationValueDef,
272
+ surface: runtimeCorrelationValueDef,
273
+ threadId: runtimeCorrelationValueDef,
274
+ turnId: runtimeCorrelationValueDef,
275
+ runId: runtimeCorrelationValueDef,
276
+ itemId: runtimeCorrelationValueDef,
277
+ toolCallId: runtimeCorrelationValueDef,
278
+ approvalId: runtimeCorrelationValueDef,
279
+ pluginId: runtimeCorrelationValueDef,
280
+ sessionKey: runtimeCorrelationValueDef,
281
+ nodeId: runtimeCorrelationValueDef,
282
+ handles: {
283
+ type: 'object',
284
+ maxProperties: VERB_LIMITS.nativeHandles,
285
+ propertyNames: { pattern: VERB_ID_PATTERNS.runtimeHandleKey },
286
+ additionalProperties: runtimeCorrelationValueDef,
287
+ },
288
+ },
289
+ };
290
+ const sessionConfigValueDef = {
291
+ type: 'string',
292
+ pattern: VERB_ID_PATTERNS.runtimeOptionValue,
293
+ maxLength: VERB_LIMITS.sessionConfigValueChars,
294
+ };
295
+ export const VERB_SESSION_CONFIG_JSON_SCHEMA = {
296
+ type: 'object',
297
+ description: 'Typed setup policy for an agent target. Values are stable runtime-advertised '
298
+ + 'option ids and are validated against the target descriptor before session creation; '
299
+ + 'labels, prompts, workspace paths, and arbitrary fields are not permitted.',
300
+ additionalProperties: false,
301
+ properties: {
302
+ model: sessionConfigValueDef,
303
+ permissionMode: sessionConfigValueDef,
304
+ effort: sessionConfigValueDef,
305
+ workspaceId: {
306
+ type: 'string',
307
+ pattern: VERB_ID_PATTERNS.workspaceOptionId,
308
+ maxLength: VERB_LIMITS.sessionConfigValueChars,
309
+ },
310
+ executionMode: { enum: ['worktree', 'locked'] },
311
+ runtimeControlValues: {
312
+ type: 'object',
313
+ maxProperties: VERB_LIMITS.sessionConfigValues,
314
+ propertyNames: {
315
+ pattern: VERB_ID_PATTERNS.runtimeControlId,
316
+ not: {
317
+ enum: [
318
+ 'model',
319
+ 'workspace',
320
+ 'executionMode',
321
+ 'permissionMode',
322
+ 'effort',
323
+ 'interrupt',
324
+ 'runtimeControlValues',
325
+ 'updatedAt',
326
+ 'updatedBy',
327
+ ],
328
+ },
329
+ },
330
+ additionalProperties: sessionConfigValueDef,
331
+ },
332
+ },
256
333
  };
257
334
  const timeoutFields = (maxMs, ceilingNote) => ({
258
335
  timeoutMs: {
@@ -308,7 +385,7 @@ const send_to_input = {
308
385
  },
309
386
  sessionSelection: REF('sessionSelection'),
310
387
  sessionConfig: {
311
- type: ['object', 'null'],
388
+ oneOf: [REF('sessionConfig'), { type: 'null' }],
312
389
  description: 'Coding-agent session setup (model/permissionMode/effort/workspaceId/executionMode); '
313
390
  + 'only applied to agent targets, stripped for humans.',
314
391
  },
@@ -1000,7 +1077,8 @@ export const CANON_VERBS_JSON_SCHEMA = {
1000
1077
  unifiedDiff: unifiedDiffDef,
1001
1078
  sessionRule: sessionRuleDef,
1002
1079
  runtimeCard: runtimeCardDef,
1003
- native: nativeDef,
1080
+ native: VERB_NATIVE_METADATA_JSON_SCHEMA,
1081
+ sessionConfig: VERB_SESSION_CONFIG_JSON_SCHEMA,
1004
1082
  send_to_input,
1005
1083
  send_to_result,
1006
1084
  request_input_input,