@datalayer/agent-runtimes 1.3.15 โ†’ 1.3.17

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 (81) hide show
  1. package/README.md +1 -1
  2. package/lib/chat/base/ChatBase.js +3 -2
  3. package/lib/config/AgentConfiguration.d.ts +1 -1
  4. package/lib/loop/apps/AppRenderer.d.ts +24 -0
  5. package/lib/loop/apps/AppRenderer.js +101 -0
  6. package/lib/loop/apps/appspec.d.ts +69 -0
  7. package/lib/loop/apps/appspec.js +566 -0
  8. package/lib/loop/apps/checks.d.ts +21 -0
  9. package/lib/loop/apps/checks.js +556 -0
  10. package/lib/loop/apps/index.d.ts +10 -0
  11. package/lib/loop/apps/index.js +14 -0
  12. package/lib/loop/apps/rules.d.ts +64 -0
  13. package/lib/loop/apps/rules.js +289 -0
  14. package/lib/loop/apps/yaml.d.ts +17 -0
  15. package/lib/loop/apps/yaml.js +185 -0
  16. package/lib/loop/embed/LoopEmbed.d.ts +6 -1
  17. package/lib/loop/embed/LoopEmbed.js +3 -2
  18. package/lib/loop/index.d.ts +1 -0
  19. package/lib/loop/index.js +3 -0
  20. package/lib/loop/plugins/chat/ChatView.js +9 -4
  21. package/lib/loop/plugins/chat/index.d.ts +10 -0
  22. package/lib/loop/plugins/chat/index.js +1 -0
  23. package/lib/loop/presets.d.ts +6 -0
  24. package/lib/loop/presets.js +2 -1
  25. package/lib/loop/shell/LoopWorkspace.d.ts +14 -0
  26. package/lib/loop/shell/LoopWorkspace.js +20 -6
  27. package/lib/loop/shell/index.d.ts +1 -1
  28. package/lib/loop/shell/index.js +1 -1
  29. package/lib/loop/shell/useWorkspaceFullScreen.d.ts +17 -4
  30. package/lib/loop/shell/useWorkspaceFullScreen.js +23 -6
  31. package/lib/specs/actions.d.ts +30 -0
  32. package/lib/specs/actions.js +616 -0
  33. package/lib/specs/agents/agents.d.ts +1 -0
  34. package/lib/specs/agents/agents.js +338 -284
  35. package/lib/specs/apps.d.ts +25 -0
  36. package/lib/specs/apps.js +1064 -0
  37. package/lib/specs/cogs.d.ts +19 -0
  38. package/lib/specs/cogs.js +736 -0
  39. package/lib/specs/events.d.ts +6 -1
  40. package/lib/specs/events.js +144 -1
  41. package/lib/specs/frames.d.ts +19 -0
  42. package/lib/specs/frames.js +444 -0
  43. package/lib/specs/gates.d.ts +22 -0
  44. package/lib/specs/gates.js +177 -0
  45. package/lib/specs/guards.d.ts +26 -0
  46. package/lib/specs/guards.js +930 -0
  47. package/lib/specs/index.d.ts +10 -0
  48. package/lib/specs/index.js +10 -0
  49. package/lib/specs/mcpServers.js +2 -2
  50. package/lib/specs/memory.js +4 -0
  51. package/lib/specs/modelProviders.d.ts +22 -0
  52. package/lib/specs/modelProviders.js +102 -0
  53. package/lib/specs/models.d.ts +31 -0
  54. package/lib/specs/models.js +215 -0
  55. package/lib/specs/ops.d.ts +15 -0
  56. package/lib/specs/ops.js +1272 -0
  57. package/lib/specs/outputs.js +2 -2
  58. package/lib/specs/skills.js +1 -1
  59. package/lib/specs/teams/teams.js +18 -18
  60. package/lib/specs/tracks.d.ts +15 -0
  61. package/lib/specs/tracks.js +87 -0
  62. package/lib/specs/uiPlugins.d.ts +16 -0
  63. package/lib/specs/uiPlugins.js +40 -0
  64. package/lib/types/agentspecs.d.ts +453 -2
  65. package/lib/types/memory.d.ts +2 -0
  66. package/lib/types/models.d.ts +52 -0
  67. package/package.json +2 -1
  68. package/scripts/check-cloudflare-models.py +122 -0
  69. package/scripts/codegen/agentspecs_clone.py +53 -0
  70. package/scripts/codegen/compose.py +65 -0
  71. package/scripts/codegen/generate_agents.py +14 -4
  72. package/scripts/codegen/generate_apps.py +454 -0
  73. package/scripts/codegen/generate_cogs.py +308 -0
  74. package/scripts/codegen/generate_frames.py +278 -0
  75. package/scripts/codegen/generate_memory.py +2 -0
  76. package/scripts/codegen/generate_model_providers.py +246 -0
  77. package/scripts/codegen/generate_models.py +135 -4
  78. package/scripts/codegen/generate_ops.py +388 -0
  79. package/scripts/codegen/generate_sandbox_agents.py +1 -1
  80. package/scripts/codegen/generate_ui_plugins.py +226 -0
  81. package/scripts/gen_workers.py +2 -2
@@ -0,0 +1,1272 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export const OP_SALES_PIPELINE_BOARD_REPORT_0_0_1 = {
6
+ id: 'op-sales-pipeline-board-report',
7
+ version: '0.0.1',
8
+ name: 'Sales Pipeline Board Report',
9
+ description: 'Builds the sales pipeline report for the board: figures computed from the pipeline data by the definitions the sales organization uses, checked against their sources and by an independent path, reviewed by Finance, and approved by a person before they reach the board.',
10
+ owner: 'Datalayer Finance <info@datalayer.io>',
11
+ goal: "Produce the board's sales pipeline report for the period โ€” stage health, conversion, weighted forecast, regional performance and risks โ€” with every figure traceable to the pipeline data.",
12
+ cogs: [
13
+ {
14
+ id: 'cog-sales-pipeline-board-report',
15
+ agent: 'worker-sales-pipeline-board-report',
16
+ frames: ['sales-pipeline', 'board-reporting'],
17
+ kind: 'context',
18
+ },
19
+ ],
20
+ frames: ['datalayer'],
21
+ supervisor: {
22
+ model: 'bedrock:us.anthropic.claude-sonnet-4-6',
23
+ instructions: 'Run the Cog on the pipeline data of the period. Send a step back to the Cog when a Gate asks for a retry or a revision, with what the Guard found. Never release the report yourself: it leaves through the release approval Gate.',
24
+ },
25
+ guards: {
26
+ preflight: [
27
+ {
28
+ identity_provider: 'datalayer',
29
+ identity_name: 'alice@acme.com',
30
+ permissions: {
31
+ 'read:data': true,
32
+ 'write:data': false,
33
+ 'execute:code': true,
34
+ 'access:internet': true,
35
+ 'send:email': false,
36
+ 'deploy:production': false,
37
+ },
38
+ token_limits: {
39
+ per_run: '50K',
40
+ per_day: '500K',
41
+ per_month: '5M',
42
+ },
43
+ data_scope: {
44
+ allowed_systems: [],
45
+ allowed_objects: [],
46
+ denied_objects: [],
47
+ denied_fields: [],
48
+ },
49
+ data_handling: {
50
+ default_aggregation: false,
51
+ allow_row_level_output: true,
52
+ max_rows_in_output: 1000,
53
+ redact_fields: [],
54
+ hash_fields: [],
55
+ pii_detection: false,
56
+ pii_action: 'warn',
57
+ },
58
+ approval_policy: {
59
+ require_manual_approval_for: [],
60
+ auto_approved: ['All read-only queries'],
61
+ },
62
+ tool_limits: {
63
+ max_tool_calls: 50,
64
+ max_query_rows: 100000,
65
+ max_query_runtime: '60s',
66
+ max_time_window_days: 90,
67
+ },
68
+ audit: {
69
+ log_tool_calls: true,
70
+ log_query_metadata_only: false,
71
+ retain_days: 30,
72
+ require_lineage_in_report: false,
73
+ },
74
+ content_safety: {
75
+ treat_crm_text_fields_as_untrusted: false,
76
+ do_not_follow_instructions_from_data: true,
77
+ },
78
+ id: 'required-frame-guard',
79
+ version: '0.0.1',
80
+ name: 'Required Frame Guard',
81
+ description: "Checks, before any work starts, that every Frame the Op and its Cogs declare exists, is enabled and has been applied to the Cogs' context.",
82
+ category: 'policy-safety',
83
+ stages: ['preflight'],
84
+ method: 'algorithmic',
85
+ check: 'Every Frame named by the Op and by its Cogs resolves, is enabled, and appears in the context each Cog was given.',
86
+ signals: [
87
+ {
88
+ name: 'frames_missing',
89
+ type: 'boolean',
90
+ description: 'A declared Frame is absent, disabled or was not applied.',
91
+ },
92
+ ],
93
+ required: true,
94
+ enabled: true,
95
+ tags: ['frames', 'configuration'],
96
+ guardrail: 'default-platform-user',
97
+ icon: 'shield-check',
98
+ emoji: '๐Ÿ›ก๏ธ',
99
+ },
100
+ {
101
+ identity_provider: 'datalayer',
102
+ identity_name: 'alice@acme.com',
103
+ permissions: {
104
+ 'read:data': true,
105
+ 'write:data': false,
106
+ 'execute:code': true,
107
+ 'access:internet': true,
108
+ 'send:email': false,
109
+ 'deploy:production': false,
110
+ },
111
+ token_limits: {
112
+ per_run: '50K',
113
+ per_day: '500K',
114
+ per_month: '5M',
115
+ },
116
+ data_scope: {
117
+ allowed_systems: [],
118
+ allowed_objects: [],
119
+ denied_objects: [],
120
+ denied_fields: [],
121
+ },
122
+ data_handling: {
123
+ default_aggregation: false,
124
+ allow_row_level_output: true,
125
+ max_rows_in_output: 1000,
126
+ redact_fields: [],
127
+ hash_fields: [],
128
+ pii_detection: false,
129
+ pii_action: 'warn',
130
+ },
131
+ approval_policy: {
132
+ require_manual_approval_for: [],
133
+ auto_approved: ['All read-only queries'],
134
+ },
135
+ tool_limits: {
136
+ max_tool_calls: 50,
137
+ max_query_rows: 100000,
138
+ max_query_runtime: '60s',
139
+ max_time_window_days: 90,
140
+ },
141
+ audit: {
142
+ log_tool_calls: true,
143
+ log_query_metadata_only: false,
144
+ retain_days: 30,
145
+ require_lineage_in_report: false,
146
+ },
147
+ content_safety: {
148
+ treat_crm_text_fields_as_untrusted: false,
149
+ do_not_follow_instructions_from_data: true,
150
+ },
151
+ id: 'permission-guard',
152
+ version: '0.0.1',
153
+ name: 'Permission Guard',
154
+ description: "Checks that the person or the system launching the Op holds every permission the Op's Cogs need, as the guardrail states them.",
155
+ category: 'policy-safety',
156
+ stages: ['preflight'],
157
+ method: 'algorithmic',
158
+ check: "Each permission the Op's Cogs use is granted to the launching identity by the guardrail; nothing the guardrail denies is requested.",
159
+ signals: [
160
+ {
161
+ name: 'permission_denied',
162
+ type: 'boolean',
163
+ description: 'A permission the Op needs is not granted.',
164
+ },
165
+ ],
166
+ required: true,
167
+ enabled: true,
168
+ tags: ['permissions', 'identity'],
169
+ guardrail: 'default-platform-user',
170
+ icon: 'shield-check',
171
+ emoji: '๐Ÿ›ก๏ธ',
172
+ },
173
+ {
174
+ identity_provider: 'datalayer',
175
+ identity_name: 'dave@acme.com',
176
+ permissions: {
177
+ 'read:data': true,
178
+ 'write:data': true,
179
+ 'execute:code': true,
180
+ 'access:internet': true,
181
+ 'send:email': true,
182
+ 'deploy:production': true,
183
+ },
184
+ token_limits: {
185
+ per_run: '200K',
186
+ per_day: '5M',
187
+ per_month: '50M',
188
+ },
189
+ data_scope: {
190
+ allowed_systems: ['postgresql', 'mongodb', 's3', 'kafka'],
191
+ allowed_objects: [],
192
+ denied_objects: [],
193
+ denied_fields: ['*SSN*', '*Bank*', '*IBAN*'],
194
+ },
195
+ data_handling: {
196
+ default_aggregation: false,
197
+ allow_row_level_output: true,
198
+ max_rows_in_output: 100000,
199
+ redact_fields: [],
200
+ hash_fields: [],
201
+ pii_detection: true,
202
+ pii_action: 'redact',
203
+ },
204
+ approval_policy: {
205
+ require_manual_approval_for: [
206
+ 'Schema changes',
207
+ 'Drop or truncate operations',
208
+ 'Production data modifications',
209
+ ],
210
+ auto_approved: [
211
+ 'Read queries',
212
+ 'Data transformations',
213
+ 'Pipeline orchestration',
214
+ ],
215
+ },
216
+ tool_limits: {
217
+ max_tool_calls: 500,
218
+ max_query_rows: 1000000,
219
+ max_query_runtime: '300s',
220
+ max_time_window_days: 365,
221
+ },
222
+ audit: {
223
+ log_tool_calls: true,
224
+ log_query_metadata_only: false,
225
+ retain_days: 90,
226
+ require_lineage_in_report: true,
227
+ },
228
+ content_safety: {
229
+ treat_crm_text_fields_as_untrusted: true,
230
+ do_not_follow_instructions_from_data: true,
231
+ },
232
+ id: 'data-source-authorization-guard',
233
+ version: '0.0.1',
234
+ name: 'Data Source Authorization Guard',
235
+ description: 'Checks that each system, object and field the Op is about to read is inside the data scope of the guardrail, and that no denied field is requested.',
236
+ category: 'policy-safety',
237
+ stages: ['preflight'],
238
+ method: 'algorithmic',
239
+ check: "Every data source named by the run is among the guardrail's allowed systems and objects; none is a denied object or matches a denied field.",
240
+ signals: [
241
+ {
242
+ name: 'unauthorized_source',
243
+ type: 'boolean',
244
+ description: 'A data source outside the allowed scope is requested.',
245
+ },
246
+ ],
247
+ required: true,
248
+ enabled: true,
249
+ tags: ['data', 'authorization'],
250
+ guardrail: 'data-engineering-power-user',
251
+ icon: 'shield-check',
252
+ emoji: '๐Ÿ›ก๏ธ',
253
+ },
254
+ ],
255
+ inFlight: [
256
+ {
257
+ identity_provider: 'datalayer',
258
+ identity_name: 'alice@acme.com',
259
+ permissions: {
260
+ 'read:data': true,
261
+ 'write:data': false,
262
+ 'execute:code': true,
263
+ 'access:internet': true,
264
+ 'send:email': false,
265
+ 'deploy:production': false,
266
+ },
267
+ token_limits: {
268
+ per_run: '50K',
269
+ per_day: '500K',
270
+ per_month: '5M',
271
+ },
272
+ data_scope: {
273
+ allowed_systems: [],
274
+ allowed_objects: [],
275
+ denied_objects: [],
276
+ denied_fields: [],
277
+ },
278
+ data_handling: {
279
+ default_aggregation: false,
280
+ allow_row_level_output: true,
281
+ max_rows_in_output: 1000,
282
+ redact_fields: [],
283
+ hash_fields: [],
284
+ pii_detection: false,
285
+ pii_action: 'warn',
286
+ },
287
+ approval_policy: {
288
+ require_manual_approval_for: [],
289
+ auto_approved: ['All read-only queries'],
290
+ },
291
+ tool_limits: {
292
+ max_tool_calls: 50,
293
+ max_query_rows: 100000,
294
+ max_query_runtime: '60s',
295
+ max_time_window_days: 90,
296
+ },
297
+ audit: {
298
+ log_tool_calls: true,
299
+ log_query_metadata_only: false,
300
+ retain_days: 30,
301
+ require_lineage_in_report: false,
302
+ },
303
+ content_safety: {
304
+ treat_crm_text_fields_as_untrusted: false,
305
+ do_not_follow_instructions_from_data: true,
306
+ },
307
+ id: 'tool-use-policy-guard',
308
+ version: '0.0.1',
309
+ name: 'Tool Use Policy Guard',
310
+ description: "Watches each tool call a Cog makes: the tool is one the Cog declares, and the calls stay within the guardrail's tool limits.",
311
+ category: 'policy-safety',
312
+ stages: ['in_flight'],
313
+ method: 'algorithmic',
314
+ check: "Every tool called is declared by the calling Cog; the number of calls, the rows queried and the query runtime stay within the guardrail's limits.",
315
+ signals: [
316
+ {
317
+ name: 'tool_violation',
318
+ type: 'boolean',
319
+ description: 'An undeclared tool was called, or a tool limit was exceeded.',
320
+ },
321
+ ],
322
+ required: true,
323
+ enabled: true,
324
+ tags: ['tools', 'limits'],
325
+ guardrail: 'default-platform-user',
326
+ icon: 'shield-check',
327
+ emoji: '๐Ÿ›ก๏ธ',
328
+ },
329
+ {
330
+ identity_provider: 'azure-ad',
331
+ identity_name: 'viewer-group@acme.onmicrosoft.com',
332
+ permissions: {
333
+ 'read:data': true,
334
+ 'write:data': false,
335
+ 'execute:code': false,
336
+ 'access:internet': false,
337
+ 'send:email': false,
338
+ 'deploy:production': false,
339
+ },
340
+ token_limits: {
341
+ per_run: '10K',
342
+ per_day: '50K',
343
+ per_month: '500K',
344
+ },
345
+ data_scope: {
346
+ allowed_systems: [],
347
+ allowed_objects: [],
348
+ denied_objects: [],
349
+ denied_fields: [
350
+ '*SSN*',
351
+ '*Bank*',
352
+ '*IBAN*',
353
+ '*Password*',
354
+ '*Secret*',
355
+ ],
356
+ },
357
+ data_handling: {
358
+ default_aggregation: true,
359
+ allow_row_level_output: false,
360
+ max_rows_in_output: 0,
361
+ redact_fields: [],
362
+ hash_fields: [],
363
+ pii_detection: true,
364
+ pii_action: 'redact',
365
+ },
366
+ approval_policy: {
367
+ require_manual_approval_for: ['Any operation beyond read'],
368
+ auto_approved: ['Aggregated read-only queries'],
369
+ },
370
+ tool_limits: {
371
+ max_tool_calls: 10,
372
+ max_query_rows: 10000,
373
+ max_query_runtime: '15s',
374
+ max_time_window_days: 30,
375
+ },
376
+ audit: {
377
+ log_tool_calls: true,
378
+ log_query_metadata_only: true,
379
+ retain_days: 90,
380
+ require_lineage_in_report: false,
381
+ },
382
+ content_safety: {
383
+ treat_crm_text_fields_as_untrusted: true,
384
+ do_not_follow_instructions_from_data: true,
385
+ },
386
+ id: 'sensitive-data-guard',
387
+ version: '0.0.1',
388
+ name: 'Sensitive Data Guard',
389
+ description: "Detects personal data, credentials and the guardrail's denied fields in what a Cog is about to send out, and in the final output.",
390
+ category: 'policy-safety',
391
+ stages: ['in_flight', 'post_run'],
392
+ method: 'algorithmic',
393
+ check: "No output, tool argument or outbound message contains a credential, a field matching the guardrail's denied fields, or personal data the guardrail's handling rules require to be redacted.",
394
+ signals: [
395
+ {
396
+ name: 'sensitive_data_detected',
397
+ type: 'boolean',
398
+ description: 'Sensitive data was found where it must not be.',
399
+ },
400
+ ],
401
+ required: true,
402
+ enabled: true,
403
+ tags: ['privacy', 'pii', 'secrets'],
404
+ guardrail: 'restricted-viewer',
405
+ icon: 'shield-check',
406
+ emoji: '๐Ÿ›ก๏ธ',
407
+ },
408
+ {
409
+ identity_provider: 'datalayer',
410
+ identity_name: 'alice@acme.com',
411
+ permissions: {
412
+ 'read:data': true,
413
+ 'write:data': false,
414
+ 'execute:code': true,
415
+ 'access:internet': true,
416
+ 'send:email': false,
417
+ 'deploy:production': false,
418
+ },
419
+ token_limits: {
420
+ per_run: '50K',
421
+ per_day: '500K',
422
+ per_month: '5M',
423
+ },
424
+ data_scope: {
425
+ allowed_systems: [],
426
+ allowed_objects: [],
427
+ denied_objects: [],
428
+ denied_fields: [],
429
+ },
430
+ data_handling: {
431
+ default_aggregation: false,
432
+ allow_row_level_output: true,
433
+ max_rows_in_output: 1000,
434
+ redact_fields: [],
435
+ hash_fields: [],
436
+ pii_detection: false,
437
+ pii_action: 'warn',
438
+ },
439
+ approval_policy: {
440
+ require_manual_approval_for: [],
441
+ auto_approved: ['All read-only queries'],
442
+ },
443
+ tool_limits: {
444
+ max_tool_calls: 50,
445
+ max_query_rows: 100000,
446
+ max_query_runtime: '60s',
447
+ max_time_window_days: 90,
448
+ },
449
+ audit: {
450
+ log_tool_calls: true,
451
+ log_query_metadata_only: false,
452
+ retain_days: 30,
453
+ require_lineage_in_report: false,
454
+ },
455
+ content_safety: {
456
+ treat_crm_text_fields_as_untrusted: false,
457
+ do_not_follow_instructions_from_data: true,
458
+ },
459
+ id: 'confidence-guard',
460
+ version: '0.0.1',
461
+ name: 'Confidence Guard',
462
+ description: 'Collects the confidence each Cog reports on its result, and the lowest of them for the run, so that a Gate can route unsure work to a person.',
463
+ category: 'algorithmic',
464
+ stages: ['in_flight', 'post_run'],
465
+ method: 'algorithmic',
466
+ check: 'Each Cog result carries a confidence between 0 and 1; the Guard reports the lowest, and fails when a result carries none.',
467
+ signals: [
468
+ {
469
+ name: 'confidence',
470
+ type: 'number',
471
+ description: 'The lowest confidence a Cog reported, between 0 and 1.',
472
+ },
473
+ ],
474
+ required: true,
475
+ enabled: true,
476
+ tags: ['confidence'],
477
+ guardrail: 'default-platform-user',
478
+ icon: 'shield-check',
479
+ emoji: '๐Ÿ›ก๏ธ',
480
+ },
481
+ ],
482
+ postRun: [
483
+ {
484
+ identity_provider: 'datalayer',
485
+ identity_name: 'alice@acme.com',
486
+ permissions: {
487
+ 'read:data': true,
488
+ 'write:data': false,
489
+ 'execute:code': true,
490
+ 'access:internet': true,
491
+ 'send:email': false,
492
+ 'deploy:production': false,
493
+ },
494
+ token_limits: {
495
+ per_run: '50K',
496
+ per_day: '500K',
497
+ per_month: '5M',
498
+ },
499
+ data_scope: {
500
+ allowed_systems: [],
501
+ allowed_objects: [],
502
+ denied_objects: [],
503
+ denied_fields: [],
504
+ },
505
+ data_handling: {
506
+ default_aggregation: false,
507
+ allow_row_level_output: true,
508
+ max_rows_in_output: 1000,
509
+ redact_fields: [],
510
+ hash_fields: [],
511
+ pii_detection: false,
512
+ pii_action: 'warn',
513
+ },
514
+ approval_policy: {
515
+ require_manual_approval_for: [],
516
+ auto_approved: ['All read-only queries'],
517
+ },
518
+ tool_limits: {
519
+ max_tool_calls: 50,
520
+ max_query_rows: 100000,
521
+ max_query_runtime: '60s',
522
+ max_time_window_days: 90,
523
+ },
524
+ audit: {
525
+ log_tool_calls: true,
526
+ log_query_metadata_only: false,
527
+ retain_days: 30,
528
+ require_lineage_in_report: false,
529
+ },
530
+ content_safety: {
531
+ treat_crm_text_fields_as_untrusted: false,
532
+ do_not_follow_instructions_from_data: true,
533
+ },
534
+ id: 'schema-guard',
535
+ version: '0.0.1',
536
+ name: 'Schema Guard',
537
+ description: "Validates the structure of the output against the schema the Op's output declares: required sections, fields, types.",
538
+ category: 'algorithmic',
539
+ stages: ['post_run'],
540
+ method: 'algorithmic',
541
+ check: 'The output validates against its declared schema: every required section and field is present and of the declared type.',
542
+ signals: [
543
+ {
544
+ name: 'schema_valid',
545
+ type: 'boolean',
546
+ description: 'The output conforms to its schema.',
547
+ },
548
+ ],
549
+ required: true,
550
+ enabled: true,
551
+ tags: ['schema', 'structure'],
552
+ guardrail: 'default-platform-user',
553
+ icon: 'shield-check',
554
+ emoji: '๐Ÿ›ก๏ธ',
555
+ },
556
+ {
557
+ identity_provider: 'datalayer',
558
+ identity_name: 'alice@acme.com',
559
+ permissions: {
560
+ 'read:data': true,
561
+ 'write:data': false,
562
+ 'execute:code': true,
563
+ 'access:internet': true,
564
+ 'send:email': false,
565
+ 'deploy:production': false,
566
+ },
567
+ token_limits: {
568
+ per_run: '50K',
569
+ per_day: '500K',
570
+ per_month: '5M',
571
+ },
572
+ data_scope: {
573
+ allowed_systems: [],
574
+ allowed_objects: [],
575
+ denied_objects: [],
576
+ denied_fields: [],
577
+ },
578
+ data_handling: {
579
+ default_aggregation: false,
580
+ allow_row_level_output: true,
581
+ max_rows_in_output: 1000,
582
+ redact_fields: [],
583
+ hash_fields: [],
584
+ pii_detection: false,
585
+ pii_action: 'warn',
586
+ },
587
+ approval_policy: {
588
+ require_manual_approval_for: [],
589
+ auto_approved: ['All read-only queries'],
590
+ },
591
+ tool_limits: {
592
+ max_tool_calls: 50,
593
+ max_query_rows: 100000,
594
+ max_query_runtime: '60s',
595
+ max_time_window_days: 90,
596
+ },
597
+ audit: {
598
+ log_tool_calls: true,
599
+ log_query_metadata_only: false,
600
+ retain_days: 30,
601
+ require_lineage_in_report: false,
602
+ },
603
+ content_safety: {
604
+ treat_crm_text_fields_as_untrusted: false,
605
+ do_not_follow_instructions_from_data: true,
606
+ },
607
+ id: 'source-grounding-guard',
608
+ version: '0.0.1',
609
+ name: 'Source Grounding Guard',
610
+ description: 'Checks each claim and each figure of the output against the sources and the computations the run used: a figure traces to the code that produced it.',
611
+ category: 'source-grounding',
612
+ stages: ['post_run'],
613
+ method: 'cog',
614
+ check: 'Every factual claim cites a source that supports it, and every figure equals the value computed in the sandbox from the authorized data.',
615
+ signals: [
616
+ {
617
+ name: 'unsupported_claims',
618
+ type: 'number',
619
+ description: 'How many claims or figures have no supporting source or computation.',
620
+ },
621
+ ],
622
+ required: true,
623
+ enabled: true,
624
+ tags: ['sources', 'evidence'],
625
+ guardrail: 'default-platform-user',
626
+ icon: 'shield-check',
627
+ emoji: '๐Ÿ›ก๏ธ',
628
+ },
629
+ {
630
+ identity_provider: 'datalayer',
631
+ identity_name: 'alice@acme.com',
632
+ permissions: {
633
+ 'read:data': true,
634
+ 'write:data': false,
635
+ 'execute:code': true,
636
+ 'access:internet': true,
637
+ 'send:email': false,
638
+ 'deploy:production': false,
639
+ },
640
+ token_limits: {
641
+ per_run: '50K',
642
+ per_day: '500K',
643
+ per_month: '5M',
644
+ },
645
+ data_scope: {
646
+ allowed_systems: [],
647
+ allowed_objects: [],
648
+ denied_objects: [],
649
+ denied_fields: [],
650
+ },
651
+ data_handling: {
652
+ default_aggregation: false,
653
+ allow_row_level_output: true,
654
+ max_rows_in_output: 1000,
655
+ redact_fields: [],
656
+ hash_fields: [],
657
+ pii_detection: false,
658
+ pii_action: 'warn',
659
+ },
660
+ approval_policy: {
661
+ require_manual_approval_for: [],
662
+ auto_approved: ['All read-only queries'],
663
+ },
664
+ tool_limits: {
665
+ max_tool_calls: 50,
666
+ max_query_rows: 100000,
667
+ max_query_runtime: '60s',
668
+ max_time_window_days: 90,
669
+ },
670
+ audit: {
671
+ log_tool_calls: true,
672
+ log_query_metadata_only: false,
673
+ retain_days: 30,
674
+ require_lineage_in_report: false,
675
+ },
676
+ content_safety: {
677
+ treat_crm_text_fields_as_untrusted: false,
678
+ do_not_follow_instructions_from_data: true,
679
+ },
680
+ id: 'consensus-guard',
681
+ version: '0.0.1',
682
+ name: 'Consensus Guard',
683
+ description: 'Recomputes the key figures by an independent path โ€” another Cog, or the same Cog on another model โ€” and measures how far the two disagree.',
684
+ category: 'consensus',
685
+ stages: ['post_run'],
686
+ method: 'cog',
687
+ check: 'The key figures of the output are recomputed independently; the Guard reports the share of them on which the two paths disagree.',
688
+ signals: [
689
+ {
690
+ name: 'consensus_disagreement',
691
+ type: 'number',
692
+ description: 'The share of key figures on which independent paths disagree, between 0 and 1.',
693
+ },
694
+ ],
695
+ required: true,
696
+ enabled: true,
697
+ tags: ['consensus', 'verification'],
698
+ guardrail: 'default-platform-user',
699
+ icon: 'shield-check',
700
+ emoji: '๐Ÿ›ก๏ธ',
701
+ },
702
+ {
703
+ identity_provider: 'azure-ad',
704
+ identity_name: 'viewer-group@acme.onmicrosoft.com',
705
+ permissions: {
706
+ 'read:data': true,
707
+ 'write:data': false,
708
+ 'execute:code': false,
709
+ 'access:internet': false,
710
+ 'send:email': false,
711
+ 'deploy:production': false,
712
+ },
713
+ token_limits: {
714
+ per_run: '10K',
715
+ per_day: '50K',
716
+ per_month: '500K',
717
+ },
718
+ data_scope: {
719
+ allowed_systems: [],
720
+ allowed_objects: [],
721
+ denied_objects: [],
722
+ denied_fields: [
723
+ '*SSN*',
724
+ '*Bank*',
725
+ '*IBAN*',
726
+ '*Password*',
727
+ '*Secret*',
728
+ ],
729
+ },
730
+ data_handling: {
731
+ default_aggregation: true,
732
+ allow_row_level_output: false,
733
+ max_rows_in_output: 0,
734
+ redact_fields: [],
735
+ hash_fields: [],
736
+ pii_detection: true,
737
+ pii_action: 'redact',
738
+ },
739
+ approval_policy: {
740
+ require_manual_approval_for: ['Any operation beyond read'],
741
+ auto_approved: ['Aggregated read-only queries'],
742
+ },
743
+ tool_limits: {
744
+ max_tool_calls: 10,
745
+ max_query_rows: 10000,
746
+ max_query_runtime: '15s',
747
+ max_time_window_days: 30,
748
+ },
749
+ audit: {
750
+ log_tool_calls: true,
751
+ log_query_metadata_only: true,
752
+ retain_days: 90,
753
+ require_lineage_in_report: false,
754
+ },
755
+ content_safety: {
756
+ treat_crm_text_fields_as_untrusted: true,
757
+ do_not_follow_instructions_from_data: true,
758
+ },
759
+ id: 'sensitive-data-guard',
760
+ version: '0.0.1',
761
+ name: 'Sensitive Data Guard',
762
+ description: "Detects personal data, credentials and the guardrail's denied fields in what a Cog is about to send out, and in the final output.",
763
+ category: 'policy-safety',
764
+ stages: ['in_flight', 'post_run'],
765
+ method: 'algorithmic',
766
+ check: "No output, tool argument or outbound message contains a credential, a field matching the guardrail's denied fields, or personal data the guardrail's handling rules require to be redacted.",
767
+ signals: [
768
+ {
769
+ name: 'sensitive_data_detected',
770
+ type: 'boolean',
771
+ description: 'Sensitive data was found where it must not be.',
772
+ },
773
+ ],
774
+ required: true,
775
+ enabled: true,
776
+ tags: ['privacy', 'pii', 'secrets'],
777
+ guardrail: 'restricted-viewer',
778
+ icon: 'shield-check',
779
+ emoji: '๐Ÿ›ก๏ธ',
780
+ },
781
+ {
782
+ identity_provider: 'datalayer',
783
+ identity_name: 'alice@acme.com',
784
+ permissions: {
785
+ 'read:data': true,
786
+ 'write:data': false,
787
+ 'execute:code': true,
788
+ 'access:internet': true,
789
+ 'send:email': false,
790
+ 'deploy:production': false,
791
+ },
792
+ token_limits: {
793
+ per_run: '50K',
794
+ per_day: '500K',
795
+ per_month: '5M',
796
+ },
797
+ data_scope: {
798
+ allowed_systems: [],
799
+ allowed_objects: [],
800
+ denied_objects: [],
801
+ denied_fields: [],
802
+ },
803
+ data_handling: {
804
+ default_aggregation: false,
805
+ allow_row_level_output: true,
806
+ max_rows_in_output: 1000,
807
+ redact_fields: [],
808
+ hash_fields: [],
809
+ pii_detection: false,
810
+ pii_action: 'warn',
811
+ },
812
+ approval_policy: {
813
+ require_manual_approval_for: [],
814
+ auto_approved: ['All read-only queries'],
815
+ },
816
+ tool_limits: {
817
+ max_tool_calls: 50,
818
+ max_query_rows: 100000,
819
+ max_query_runtime: '60s',
820
+ max_time_window_days: 90,
821
+ },
822
+ audit: {
823
+ log_tool_calls: true,
824
+ log_query_metadata_only: false,
825
+ retain_days: 30,
826
+ require_lineage_in_report: false,
827
+ },
828
+ content_safety: {
829
+ treat_crm_text_fields_as_untrusted: false,
830
+ do_not_follow_instructions_from_data: true,
831
+ },
832
+ id: 'expert-sampling-guard',
833
+ version: '0.0.1',
834
+ name: 'Expert Sampling Guard',
835
+ description: 'Routes the output โ€” every one of a high-risk Op, a sample of the others โ€” to a named expert, and records what they decided.',
836
+ category: 'expert',
837
+ stages: ['post_run'],
838
+ method: 'human',
839
+ check: 'An expert in the subject reads the output and its evidence, and approves it, edits it or sends it back.',
840
+ signals: [
841
+ {
842
+ name: 'expert_approved',
843
+ type: 'boolean',
844
+ description: 'The expert approved the output.',
845
+ },
846
+ {
847
+ name: 'high_risk',
848
+ type: 'boolean',
849
+ description: 'The output is of a kind every instance of which is reviewed.',
850
+ },
851
+ ],
852
+ required: true,
853
+ enabled: true,
854
+ tags: ['expert', 'review'],
855
+ guardrail: 'default-platform-user',
856
+ icon: 'shield-check',
857
+ emoji: '๐Ÿ›ก๏ธ',
858
+ },
859
+ ],
860
+ continuous: [
861
+ {
862
+ identity_provider: 'datalayer',
863
+ identity_name: 'dave@acme.com',
864
+ permissions: {
865
+ 'read:data': true,
866
+ 'write:data': true,
867
+ 'execute:code': true,
868
+ 'access:internet': true,
869
+ 'send:email': true,
870
+ 'deploy:production': true,
871
+ },
872
+ token_limits: {
873
+ per_run: '200K',
874
+ per_day: '5M',
875
+ per_month: '50M',
876
+ },
877
+ data_scope: {
878
+ allowed_systems: ['postgresql', 'mongodb', 's3', 'kafka'],
879
+ allowed_objects: [],
880
+ denied_objects: [],
881
+ denied_fields: ['*SSN*', '*Bank*', '*IBAN*'],
882
+ },
883
+ data_handling: {
884
+ default_aggregation: false,
885
+ allow_row_level_output: true,
886
+ max_rows_in_output: 100000,
887
+ redact_fields: [],
888
+ hash_fields: [],
889
+ pii_detection: true,
890
+ pii_action: 'redact',
891
+ },
892
+ approval_policy: {
893
+ require_manual_approval_for: [
894
+ 'Schema changes',
895
+ 'Drop or truncate operations',
896
+ 'Production data modifications',
897
+ ],
898
+ auto_approved: [
899
+ 'Read queries',
900
+ 'Data transformations',
901
+ 'Pipeline orchestration',
902
+ ],
903
+ },
904
+ tool_limits: {
905
+ max_tool_calls: 500,
906
+ max_query_rows: 1000000,
907
+ max_query_runtime: '300s',
908
+ max_time_window_days: 365,
909
+ },
910
+ audit: {
911
+ log_tool_calls: true,
912
+ log_query_metadata_only: false,
913
+ retain_days: 90,
914
+ require_lineage_in_report: true,
915
+ },
916
+ content_safety: {
917
+ treat_crm_text_fields_as_untrusted: true,
918
+ do_not_follow_instructions_from_data: true,
919
+ },
920
+ id: 'regression-guard',
921
+ version: '0.0.1',
922
+ name: 'Regression Guard',
923
+ description: 'Replays a golden set of past runs after a model, a Frame, a Cog or the Op itself changes, and compares the results with the validated ones.',
924
+ category: 'regression-drift',
925
+ stages: ['continuous'],
926
+ method: 'algorithmic',
927
+ check: "On the golden set, the share of runs whose output departs from the validated one stays under the threshold the Op's owner set.",
928
+ signals: [
929
+ {
930
+ name: 'regression_rate',
931
+ type: 'number',
932
+ description: 'The share of golden runs whose output changed, between 0 and 1.',
933
+ },
934
+ ],
935
+ required: false,
936
+ enabled: true,
937
+ tags: ['regression', 'drift'],
938
+ guardrail: 'data-engineering-power-user',
939
+ icon: 'shield-check',
940
+ emoji: '๐Ÿ›ก๏ธ',
941
+ },
942
+ {
943
+ identity_provider: 'datalayer',
944
+ identity_name: 'alice@acme.com',
945
+ permissions: {
946
+ 'read:data': true,
947
+ 'write:data': false,
948
+ 'execute:code': true,
949
+ 'access:internet': true,
950
+ 'send:email': false,
951
+ 'deploy:production': false,
952
+ },
953
+ token_limits: {
954
+ per_run: '50K',
955
+ per_day: '500K',
956
+ per_month: '5M',
957
+ },
958
+ data_scope: {
959
+ allowed_systems: [],
960
+ allowed_objects: [],
961
+ denied_objects: [],
962
+ denied_fields: [],
963
+ },
964
+ data_handling: {
965
+ default_aggregation: false,
966
+ allow_row_level_output: true,
967
+ max_rows_in_output: 1000,
968
+ redact_fields: [],
969
+ hash_fields: [],
970
+ pii_detection: false,
971
+ pii_action: 'warn',
972
+ },
973
+ approval_policy: {
974
+ require_manual_approval_for: [],
975
+ auto_approved: ['All read-only queries'],
976
+ },
977
+ tool_limits: {
978
+ max_tool_calls: 50,
979
+ max_query_rows: 100000,
980
+ max_query_runtime: '60s',
981
+ max_time_window_days: 90,
982
+ },
983
+ audit: {
984
+ log_tool_calls: true,
985
+ log_query_metadata_only: false,
986
+ retain_days: 30,
987
+ require_lineage_in_report: false,
988
+ },
989
+ content_safety: {
990
+ treat_crm_text_fields_as_untrusted: false,
991
+ do_not_follow_instructions_from_data: true,
992
+ },
993
+ id: 'outcome-guard',
994
+ version: '0.0.1',
995
+ name: 'Outcome Guard',
996
+ description: "Measures, over time, whether the Op's outputs are used as intended: accepted without rework, on time, with the decision they were made for taken.",
997
+ category: 'outcome',
998
+ stages: ['continuous'],
999
+ method: 'human',
1000
+ check: "Over the review period, the share of outputs accepted without rework by the people they were produced for meets the Op's goal.",
1001
+ signals: [
1002
+ {
1003
+ name: 'outcome_met',
1004
+ type: 'boolean',
1005
+ description: 'The Op met its outcome goal over the review period.',
1006
+ },
1007
+ ],
1008
+ required: false,
1009
+ enabled: true,
1010
+ tags: ['outcome', 'value'],
1011
+ guardrail: 'default-platform-user',
1012
+ icon: 'shield-check',
1013
+ emoji: '๐Ÿ›ก๏ธ',
1014
+ },
1015
+ ],
1016
+ },
1017
+ gates: [
1018
+ {
1019
+ id: 'configuration-check',
1020
+ version: '0.0.1',
1021
+ name: 'Configuration Check',
1022
+ description: 'Stops an Op before it starts when a Frame it requires is missing, a permission is not granted or a data source is not authorized.',
1023
+ stage: 'preflight',
1024
+ guards: [
1025
+ 'required-frame-guard:0.0.1',
1026
+ 'permission-guard:0.0.1',
1027
+ 'data-source-authorization-guard:0.0.1',
1028
+ ],
1029
+ when: 'frames_missing or permission_denied or unauthorized_source',
1030
+ then: 'stop_and_escalate',
1031
+ otherwise: 'proceed',
1032
+ reviewers: ['op-owner'],
1033
+ maxRetries: 0,
1034
+ enabled: true,
1035
+ tags: ['preflight'],
1036
+ icon: 'git-branch',
1037
+ emoji: '๐Ÿšฆ',
1038
+ signals: ['frames_missing', 'permission_denied', 'unauthorized_source'],
1039
+ },
1040
+ {
1041
+ id: 'sensitive-data-stop',
1042
+ version: '0.0.1',
1043
+ name: 'Sensitive Data Stop',
1044
+ description: 'Stops the Op and tells the data protection officer when sensitive data is detected in what a Cog is about to send out, or in the output.',
1045
+ stage: 'in_flight',
1046
+ guards: ['sensitive-data-guard:0.0.1'],
1047
+ when: 'sensitive_data_detected',
1048
+ then: 'stop_and_escalate',
1049
+ otherwise: 'proceed',
1050
+ reviewers: ['data-protection-officer'],
1051
+ maxRetries: 0,
1052
+ enabled: true,
1053
+ tags: ['privacy'],
1054
+ icon: 'git-branch',
1055
+ emoji: '๐Ÿšฆ',
1056
+ signals: ['sensitive_data_detected'],
1057
+ },
1058
+ {
1059
+ id: 'tool-violation-retry',
1060
+ version: '0.0.1',
1061
+ name: 'Tool Violation Retry',
1062
+ description: 'Sends a step back to its Cog when it called a tool it does not declare or exceeded a tool limit; after the retries are used up the Op stops.',
1063
+ stage: 'in_flight',
1064
+ guards: ['tool-use-policy-guard:0.0.1'],
1065
+ when: 'tool_violation',
1066
+ then: 'retry',
1067
+ otherwise: 'proceed',
1068
+ reviewers: [],
1069
+ maxRetries: 2,
1070
+ enabled: true,
1071
+ tags: ['tools'],
1072
+ icon: 'git-branch',
1073
+ emoji: '๐Ÿšฆ',
1074
+ signals: ['tool_violation'],
1075
+ },
1076
+ {
1077
+ id: 'low-confidence-review',
1078
+ version: '0.0.1',
1079
+ name: 'Low Confidence Review',
1080
+ description: 'Routes the output to human review when the lowest confidence a Cog reported is under 0.80. Low confidence is not a failure: it is where the autonomy granted to the Op ends.',
1081
+ stage: 'post_run',
1082
+ guards: ['confidence-guard:0.0.1'],
1083
+ when: 'confidence < 0.80',
1084
+ then: 'human_review_required',
1085
+ otherwise: 'proceed',
1086
+ reviewers: ['op-owner'],
1087
+ maxRetries: 0,
1088
+ enabled: true,
1089
+ tags: ['confidence', 'human-in-the-loop'],
1090
+ icon: 'git-branch',
1091
+ emoji: '๐Ÿšฆ',
1092
+ signals: ['confidence'],
1093
+ },
1094
+ {
1095
+ id: 'unsupported-claims-revision',
1096
+ version: '0.0.1',
1097
+ name: 'Unsupported Claims Revision',
1098
+ description: 'Pauses the Op and asks for a revision when the output is not valid against its schema or carries a claim or a figure its sources do not support.',
1099
+ stage: 'post_run',
1100
+ guards: ['schema-guard:0.0.1', 'source-grounding-guard:0.0.1'],
1101
+ when: 'schema_valid == false or unsupported_claims > 0',
1102
+ then: 'pause',
1103
+ otherwise: 'proceed',
1104
+ reviewers: [],
1105
+ maxRetries: 0,
1106
+ enabled: true,
1107
+ tags: ['evidence'],
1108
+ icon: 'git-branch',
1109
+ emoji: '๐Ÿšฆ',
1110
+ signals: ['schema_valid', 'unsupported_claims'],
1111
+ },
1112
+ {
1113
+ id: 'consensus-disagreement-review',
1114
+ version: '0.0.1',
1115
+ name: 'Consensus Disagreement Review',
1116
+ description: 'Escalates to an expert when independent recomputations disagree on more than a quarter of the key figures.',
1117
+ stage: 'post_run',
1118
+ guards: ['consensus-guard:0.0.1'],
1119
+ when: 'consensus_disagreement > 0.25',
1120
+ then: 'expert_review_required',
1121
+ otherwise: 'proceed',
1122
+ reviewers: ['subject-matter-expert'],
1123
+ maxRetries: 0,
1124
+ enabled: true,
1125
+ tags: ['consensus'],
1126
+ icon: 'git-branch',
1127
+ emoji: '๐Ÿšฆ',
1128
+ signals: ['consensus_disagreement'],
1129
+ },
1130
+ {
1131
+ id: 'release-approval',
1132
+ version: '0.0.1',
1133
+ name: 'Release Approval',
1134
+ description: "Requires a person to approve the output before it is released to its audience, whatever the Guards found. The expert's review is recorded beside the approval.",
1135
+ stage: 'post_run',
1136
+ guards: ['expert-sampling-guard:0.0.1'],
1137
+ when: 'always',
1138
+ then: 'human_approval_required',
1139
+ otherwise: 'stop',
1140
+ reviewers: ['op-owner', 'finance'],
1141
+ maxRetries: 0,
1142
+ enabled: true,
1143
+ tags: ['approval', 'human-in-the-loop'],
1144
+ icon: 'git-branch',
1145
+ emoji: '๐Ÿšฆ',
1146
+ signals: [],
1147
+ },
1148
+ {
1149
+ id: 'quality-drift-review',
1150
+ version: '0.0.1',
1151
+ name: 'Quality Drift Review',
1152
+ description: 'Puts the Op before an expert when more than one golden run in ten changed after an update, or when the Op missed its outcome goal over the review period.',
1153
+ stage: 'continuous',
1154
+ guards: ['regression-guard:0.0.1', 'outcome-guard:0.0.1'],
1155
+ when: 'regression_rate > 0.10 or outcome_met == false',
1156
+ then: 'expert_review_required',
1157
+ otherwise: 'proceed',
1158
+ reviewers: ['op-owner', 'subject-matter-expert'],
1159
+ maxRetries: 0,
1160
+ enabled: true,
1161
+ tags: ['drift', 'outcome'],
1162
+ icon: 'git-branch',
1163
+ emoji: '๐Ÿšฆ',
1164
+ signals: ['regression_rate', 'outcome_met'],
1165
+ },
1166
+ ],
1167
+ track: {
1168
+ id: 'financial-reporting',
1169
+ version: '0.0.1',
1170
+ name: 'Financial Reporting Track',
1171
+ description: 'The complete record of an Op that produces financial reporting: every input and source, every model and setting, every Guard result, Gate decision, approval and edit. Kept seven years, readable by Finance and by audit, and fed back to Organizational Memory.',
1172
+ retainFor: '7_years',
1173
+ include: [
1174
+ 'op',
1175
+ 'frames_used',
1176
+ 'cogs_invoked',
1177
+ 'input_data',
1178
+ 'source_documents',
1179
+ 'model_versions',
1180
+ 'configuration',
1181
+ 'guard_results',
1182
+ 'gate_decisions',
1183
+ 'human_approvals',
1184
+ 'human_edits',
1185
+ 'final_output',
1186
+ 'actions_taken',
1187
+ 'timestamps',
1188
+ 'user_identity',
1189
+ 'permissions',
1190
+ 'environment',
1191
+ 'memory_links',
1192
+ ],
1193
+ readers: ['finance', 'internal-audit'],
1194
+ redact: ['*Password*', '*Secret*', '*Token*', '*IBAN*'],
1195
+ feedsMemory: true,
1196
+ exchangeable: false,
1197
+ enabled: true,
1198
+ tags: ['finance', 'audit'],
1199
+ icon: 'log',
1200
+ emoji: '๐Ÿงพ',
1201
+ retentionDays: 2555,
1202
+ },
1203
+ triggers: ['launcher', 'command', 'schedule'],
1204
+ enabled: false,
1205
+ tags: ['sales', 'board', 'reporting'],
1206
+ icon: 'workflow',
1207
+ emoji: '๐Ÿ“Š',
1208
+ color: '#1F883D',
1209
+ lineage: ['datalayer', 'sales-pipeline', 'board-reporting'],
1210
+ frameGuards: [
1211
+ {
1212
+ id: 'no-secrets',
1213
+ category: 'policy-safety',
1214
+ description: 'The output contains no credential, token, API key or password.',
1215
+ required: true,
1216
+ },
1217
+ {
1218
+ id: 'totals-reconcile',
1219
+ category: 'algorithmic',
1220
+ description: 'The totals by stage, by region and by segment each add up to the total pipeline.',
1221
+ required: true,
1222
+ },
1223
+ {
1224
+ id: 'definitions-applied',
1225
+ category: 'policy-safety',
1226
+ description: 'Conversion, weighted pipeline and coverage are computed as this Frame defines them.',
1227
+ required: true,
1228
+ },
1229
+ {
1230
+ id: 'data-quality-reported',
1231
+ category: 'algorithmic',
1232
+ description: 'Rows excluded from a figure, and why, are counted and reported.',
1233
+ required: true,
1234
+ },
1235
+ {
1236
+ id: 'summary-first',
1237
+ category: 'algorithmic',
1238
+ description: 'The report opens with a summary of at most one page, with the key figures, the risks and the asks.',
1239
+ required: true,
1240
+ },
1241
+ {
1242
+ id: 'forecast-labelled',
1243
+ category: 'policy-safety',
1244
+ description: 'Every forward-looking figure is labelled as a forecast and carries its assumption.',
1245
+ required: true,
1246
+ },
1247
+ {
1248
+ id: 'finance-review',
1249
+ category: 'expert',
1250
+ description: 'A person from Finance reviews the figures before the report is sent to the board.',
1251
+ required: true,
1252
+ },
1253
+ ],
1254
+ };
1255
+ export const OP_CATALOGUE = {
1256
+ 'op-sales-pipeline-board-report': OP_SALES_PIPELINE_BOARD_REPORT_0_0_1,
1257
+ };
1258
+ /** An Op, by `id` or `id:version`, or undefined. */
1259
+ export function getOp(ref) {
1260
+ // Own entries only: `constructor` and `toString` are not Ops.
1261
+ const own = (id) => Object.prototype.hasOwnProperty.call(OP_CATALOGUE, id)
1262
+ ? OP_CATALOGUE[id]
1263
+ : undefined;
1264
+ const at = ref.lastIndexOf(':');
1265
+ return (own(ref) ??
1266
+ (at > 0 && ref.slice(at + 1).includes('.')
1267
+ ? own(ref.slice(0, at))
1268
+ : undefined));
1269
+ }
1270
+ export function listOps() {
1271
+ return Object.values(OP_CATALOGUE);
1272
+ }