@datalayer/agent-runtimes 1.3.16 → 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 (41) hide show
  1. package/lib/loop/apps/AppRenderer.d.ts +24 -0
  2. package/lib/loop/apps/AppRenderer.js +101 -0
  3. package/lib/loop/apps/appspec.d.ts +69 -0
  4. package/lib/loop/apps/appspec.js +566 -0
  5. package/lib/loop/apps/checks.d.ts +21 -0
  6. package/lib/loop/apps/checks.js +556 -0
  7. package/lib/loop/apps/index.d.ts +10 -0
  8. package/lib/loop/apps/index.js +14 -0
  9. package/lib/loop/apps/rules.d.ts +64 -0
  10. package/lib/loop/apps/rules.js +289 -0
  11. package/lib/loop/apps/yaml.d.ts +17 -0
  12. package/lib/loop/apps/yaml.js +185 -0
  13. package/lib/loop/index.d.ts +1 -0
  14. package/lib/loop/index.js +3 -0
  15. package/lib/specs/actions.d.ts +30 -0
  16. package/lib/specs/actions.js +616 -0
  17. package/lib/specs/apps.d.ts +25 -0
  18. package/lib/specs/apps.js +1064 -0
  19. package/lib/specs/cogs.d.ts +19 -0
  20. package/lib/specs/cogs.js +736 -0
  21. package/lib/specs/frames.d.ts +19 -0
  22. package/lib/specs/frames.js +444 -0
  23. package/lib/specs/gates.d.ts +22 -0
  24. package/lib/specs/gates.js +177 -0
  25. package/lib/specs/guards.d.ts +26 -0
  26. package/lib/specs/guards.js +930 -0
  27. package/lib/specs/index.d.ts +8 -0
  28. package/lib/specs/index.js +8 -0
  29. package/lib/specs/ops.d.ts +15 -0
  30. package/lib/specs/ops.js +1272 -0
  31. package/lib/specs/tracks.d.ts +15 -0
  32. package/lib/specs/tracks.js +87 -0
  33. package/lib/types/agentspecs.d.ts +435 -0
  34. package/package.json +2 -1
  35. package/scripts/codegen/agentspecs_clone.py +53 -0
  36. package/scripts/codegen/compose.py +65 -0
  37. package/scripts/codegen/generate_agents.py +8 -0
  38. package/scripts/codegen/generate_apps.py +454 -0
  39. package/scripts/codegen/generate_cogs.py +308 -0
  40. package/scripts/codegen/generate_frames.py +278 -0
  41. package/scripts/codegen/generate_ops.py +388 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Frame Catalog.
3
+ *
4
+ * The context work happens in, written down: owned, scoped and inherited.
5
+ * Every Frame is resolved — what it inherits is already in it.
6
+ *
7
+ * This file is AUTO-GENERATED from YAML specifications.
8
+ * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
9
+ */
10
+ import type { FrameSpec } from '../types/agentspecs';
11
+ export declare const BOARD_REPORTING_FRAME_0_0_1: FrameSpec;
12
+ export declare const CUSTOMER_RESEARCH_FRAME_0_0_1: FrameSpec;
13
+ export declare const DATALAYER_FRAME_0_0_1: FrameSpec;
14
+ export declare const SALES_PIPELINE_FRAME_0_0_1: FrameSpec;
15
+ export declare const WEB_RESEARCH_FRAME_0_0_1: FrameSpec;
16
+ export declare const FRAME_CATALOGUE: Record<string, FrameSpec>;
17
+ /** The Frame a Cog names, by `id` or `id:version`, or undefined. */
18
+ export declare function getFrame(frameId: string): FrameSpec | undefined;
19
+ export declare function listFrames(): FrameSpec[];
@@ -0,0 +1,444 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export const BOARD_REPORTING_FRAME_0_0_1 = {
6
+ id: 'board-reporting',
7
+ version: '0.0.1',
8
+ name: 'Board Reporting Frame',
9
+ description: 'The voice, the structure and the standard of evidence of a document written for the board of directors. Composes with the Frame of the subject reported on.',
10
+ scope: 'relationship',
11
+ owner: 'Datalayer Finance <info@datalayer.io>',
12
+ extends: 'datalayer:0.0.1',
13
+ lineage: ['datalayer'],
14
+ tags: ['board', 'reporting', 'executive'],
15
+ enabled: true,
16
+ icon: 'project-roadmap',
17
+ emoji: '🏛️',
18
+ rules: [
19
+ 'Never claim a capability, a tool or a result you have not verified.',
20
+ 'Never put a secret, a credential or a token in an output.',
21
+ 'Say what you did not do and what you could not check, as plainly as what you did.',
22
+ 'Keep personal data out of an output unless the task is about that person and they are its audience.',
23
+ 'State a risk as plainly as a result; never soften a miss.',
24
+ 'Present a forecast as a forecast, with the assumption it rests on.',
25
+ 'Keep individual employees and named customers out of the report unless the board asked for them.',
26
+ ],
27
+ terminology: {
28
+ Agentspec: 'The declarative YAML specification of an agent.',
29
+ Frame: 'The context work happens in, written down, owned, versioned and inherited.',
30
+ Cog: 'An AI worker you can hold to account — an agent equipped with Frames.',
31
+ Guard: 'A check the output of a piece of work has to pass.',
32
+ Sandbox: 'The isolated environment an agent runs code in, beside the data.',
33
+ },
34
+ goals: [
35
+ 'The reader can act on the output without asking what it means.',
36
+ 'Every number can be traced to the code and the source it came from.',
37
+ 'A director who reads only the first page knows the state, the risks and the decision asked for.',
38
+ ],
39
+ style: [
40
+ 'Plain, direct sentences; the conclusion first.',
41
+ 'Name things by what they are; no marketing adjectives.',
42
+ 'Structured output — headings, short lists, tables for figures — over long prose.',
43
+ 'One page of summary first — the state, three to five key figures, the risks, the asks.',
44
+ 'Figures in tables, with the period and the comparison beside each.',
45
+ 'No jargon a director outside the function would not know; define a term at its first use.',
46
+ 'Neutral and factual; no superlatives.',
47
+ ],
48
+ norms: [
49
+ 'Run the analysis in the sandbox and report the result, not the raw data.',
50
+ 'Cite the source of every factual claim.',
51
+ 'Prefer the smallest change, and the simplest explanation, that is correct.',
52
+ 'Round to what the decision needs, and keep the units and the currency on every figure.',
53
+ 'Compare each key figure with the target and with the previous period.',
54
+ 'End with what is asked of the board, or say that nothing is.',
55
+ ],
56
+ process: [],
57
+ architecture: '',
58
+ prompts: [],
59
+ skills: [],
60
+ tools: [],
61
+ mcpServers: [],
62
+ guards: [
63
+ {
64
+ id: 'no-secrets',
65
+ category: 'policy-safety',
66
+ description: 'The output contains no credential, token, API key or password.',
67
+ required: true,
68
+ },
69
+ {
70
+ id: 'summary-first',
71
+ category: 'algorithmic',
72
+ description: 'The report opens with a summary of at most one page, with the key figures, the risks and the asks.',
73
+ required: true,
74
+ },
75
+ {
76
+ id: 'forecast-labelled',
77
+ category: 'policy-safety',
78
+ description: 'Every forward-looking figure is labelled as a forecast and carries its assumption.',
79
+ required: true,
80
+ },
81
+ {
82
+ id: 'finance-review',
83
+ category: 'expert',
84
+ description: 'A person from Finance reviews the figures before the report is sent to the board.',
85
+ required: true,
86
+ },
87
+ ],
88
+ };
89
+ export const CUSTOMER_RESEARCH_FRAME_0_0_1 = {
90
+ id: 'customer-research',
91
+ version: '0.0.1',
92
+ name: 'Customer Research Frame',
93
+ description: 'The ethics, the method and the vocabulary of qualitative customer research: how an interview is conducted, what consent covers, and how what was said becomes insight without being bent.',
94
+ scope: 'team',
95
+ owner: 'Datalayer Product Research <info@datalayer.io>',
96
+ extends: 'datalayer:0.0.1',
97
+ lineage: ['datalayer'],
98
+ tags: ['research', 'customer', 'interview'],
99
+ enabled: true,
100
+ icon: 'comment-discussion',
101
+ emoji: '🎙️',
102
+ rules: [
103
+ 'Never claim a capability, a tool or a result you have not verified.',
104
+ 'Never put a secret, a credential or a token in an output.',
105
+ 'Say what you did not do and what you could not check, as plainly as what you did.',
106
+ 'Keep personal data out of an output unless the task is about that person and they are its audience.',
107
+ 'Tell the interviewee at the start what the interview is for and how what they say will be used.',
108
+ "Never ask a leading question, and never put words in the interviewee's mouth.",
109
+ 'Stop, or move on, when the interviewee declines to answer.',
110
+ 'Report a quote verbatim, and never attribute one to a named person without their consent.',
111
+ 'Keep personal data — names, employers, contact details — out of the insights unless consent covers it.',
112
+ ],
113
+ terminology: {
114
+ Agentspec: 'The declarative YAML specification of an agent.',
115
+ Frame: 'The context work happens in, written down, owned, versioned and inherited.',
116
+ Cog: 'An AI worker you can hold to account — an agent equipped with Frames.',
117
+ Guard: 'A check the output of a piece of work has to pass.',
118
+ Sandbox: 'The isolated environment an agent runs code in, beside the data.',
119
+ Insight: 'A pattern in what interviewees said that explains a behavior or a decision, with its evidence.',
120
+ Motivation: 'Why the interviewee does what they do; what an answer is probed for.',
121
+ 'Decision driver': 'A criterion the interviewee weighed when choosing.',
122
+ Objection: 'A reason the interviewee gave against choosing, or for hesitating.',
123
+ Verbatim: "The interviewee's own words, quoted exactly.",
124
+ },
125
+ goals: [
126
+ 'The reader can act on the output without asking what it means.',
127
+ 'Every number can be traced to the code and the source it came from.',
128
+ 'Understand the why behind each answer, not only the what.',
129
+ 'Every insight can be traced to what an interviewee actually said.',
130
+ ],
131
+ style: [
132
+ 'Plain, direct sentences; the conclusion first.',
133
+ 'Name things by what they are; no marketing adjectives.',
134
+ 'Structured output — headings, short lists, tables for figures — over long prose.',
135
+ 'Warm, brief and neutral with the interviewee; one question at a time.',
136
+ 'Insights as short statements, each with the verbatims that support it.',
137
+ ],
138
+ norms: [
139
+ 'Run the analysis in the sandbox and report the result, not the raw data.',
140
+ 'Cite the source of every factual claim.',
141
+ 'Prefer the smallest change, and the simplest explanation, that is correct.',
142
+ 'Open-ended questions first; follow up on what was just said.',
143
+ 'Separate what was said from what is inferred, and mark the inference.',
144
+ 'Note what the interview did not cover.',
145
+ ],
146
+ process: [
147
+ 'Introduce the interview, its purpose and how the answers are used; ask for consent.',
148
+ 'Open with one broad question; follow each answer with a question on its why.',
149
+ 'Close when the planned ground is covered or the interviewee wants to stop.',
150
+ 'Turn the conversation into insights — motivations, decision drivers, objections, verbatims, next steps.',
151
+ ],
152
+ architecture: '',
153
+ prompts: [],
154
+ skills: ['text-summarizer:0.0.1'],
155
+ tools: [],
156
+ mcpServers: [],
157
+ guards: [
158
+ {
159
+ id: 'no-secrets',
160
+ category: 'policy-safety',
161
+ description: 'The output contains no credential, token, API key or password.',
162
+ required: true,
163
+ },
164
+ {
165
+ id: 'no-leading-questions',
166
+ category: 'policy-safety',
167
+ description: 'No question in the interview suggests its own answer.',
168
+ required: true,
169
+ },
170
+ {
171
+ id: 'insights-grounded',
172
+ category: 'source-grounding',
173
+ description: 'Every insight cites at least one verbatim from the interview that supports it.',
174
+ required: true,
175
+ },
176
+ {
177
+ id: 'personal-data-removed',
178
+ category: 'policy-safety',
179
+ description: 'The insights name no person, employer or contact detail that consent does not cover.',
180
+ required: true,
181
+ },
182
+ ],
183
+ };
184
+ export const DATALAYER_FRAME_0_0_1 = {
185
+ id: 'datalayer',
186
+ version: '0.0.1',
187
+ name: 'Datalayer Company Frame',
188
+ description: 'The vocabulary, the voice and the working rules of Datalayer. The root of the catalogue: department, team, role and relationship Frames extend it.',
189
+ scope: 'organization',
190
+ owner: 'Datalayer, Inc. <info@datalayer.io>',
191
+ lineage: [],
192
+ tags: ['company', 'baseline'],
193
+ enabled: true,
194
+ icon: 'organization',
195
+ emoji: '🏢',
196
+ rules: [
197
+ 'Never claim a capability, a tool or a result you have not verified.',
198
+ 'Never put a secret, a credential or a token in an output.',
199
+ 'Say what you did not do and what you could not check, as plainly as what you did.',
200
+ 'Keep personal data out of an output unless the task is about that person and they are its audience.',
201
+ ],
202
+ terminology: {
203
+ Agentspec: 'The declarative YAML specification of an agent.',
204
+ Frame: 'The context work happens in, written down, owned, versioned and inherited.',
205
+ Cog: 'An AI worker you can hold to account — an agent equipped with Frames.',
206
+ Guard: 'A check the output of a piece of work has to pass.',
207
+ Sandbox: 'The isolated environment an agent runs code in, beside the data.',
208
+ },
209
+ goals: [
210
+ 'The reader can act on the output without asking what it means.',
211
+ 'Every number can be traced to the code and the source it came from.',
212
+ ],
213
+ style: [
214
+ 'Plain, direct sentences; the conclusion first.',
215
+ 'Name things by what they are; no marketing adjectives.',
216
+ 'Structured output — headings, short lists, tables for figures — over long prose.',
217
+ ],
218
+ norms: [
219
+ 'Run the analysis in the sandbox and report the result, not the raw data.',
220
+ 'Cite the source of every factual claim.',
221
+ 'Prefer the smallest change, and the simplest explanation, that is correct.',
222
+ ],
223
+ process: [],
224
+ architecture: '',
225
+ prompts: [],
226
+ skills: [],
227
+ tools: [],
228
+ mcpServers: [],
229
+ guards: [
230
+ {
231
+ id: 'no-secrets',
232
+ category: 'policy-safety',
233
+ description: 'The output contains no credential, token, API key or password.',
234
+ required: true,
235
+ },
236
+ ],
237
+ };
238
+ export const SALES_PIPELINE_FRAME_0_0_1 = {
239
+ id: 'sales-pipeline',
240
+ version: '0.0.1',
241
+ name: 'Sales Pipeline Frame',
242
+ description: 'How the sales organization names, measures and reports its pipeline: the stages, the definitions of conversion and weighted forecast, and the checks a pipeline figure has to pass.',
243
+ scope: 'department',
244
+ owner: 'Datalayer Sales <info@datalayer.io>',
245
+ extends: 'datalayer:0.0.1',
246
+ lineage: ['datalayer'],
247
+ tags: ['sales', 'pipeline', 'forecast'],
248
+ enabled: true,
249
+ icon: 'graph',
250
+ emoji: '📈',
251
+ rules: [
252
+ 'Never claim a capability, a tool or a result you have not verified.',
253
+ 'Never put a secret, a credential or a token in an output.',
254
+ 'Say what you did not do and what you could not check, as plainly as what you did.',
255
+ 'Keep personal data out of an output unless the task is about that person and they are its audience.',
256
+ 'Compute every figure from the pipeline data in the sandbox; never estimate one.',
257
+ 'Never change, drop or impute a deal to make totals agree; report the discrepancy.',
258
+ 'Name a customer or a deal owner only when the audience of the report is internal.',
259
+ ],
260
+ terminology: {
261
+ Agentspec: 'The declarative YAML specification of an agent.',
262
+ Frame: 'The context work happens in, written down, owned, versioned and inherited.',
263
+ Cog: 'An AI worker you can hold to account — an agent equipped with Frames.',
264
+ Guard: 'A check the output of a piece of work has to pass.',
265
+ Sandbox: 'The isolated environment an agent runs code in, beside the data.',
266
+ Pipeline: 'The open opportunities, each at a stage, with an amount and an expected close date.',
267
+ Stage: 'Where an opportunity stands, from first qualification to closed won or closed lost.',
268
+ 'Stage conversion': 'The share of opportunities that entered a stage and moved on to the next.',
269
+ 'Weighted pipeline': "The sum of each open opportunity's amount multiplied by its stage's probability of closing.",
270
+ Coverage: 'Weighted or total open pipeline divided by the target of the period.',
271
+ Slippage: 'Opportunities whose expected close date moved out of the period.',
272
+ },
273
+ goals: [
274
+ 'The reader can act on the output without asking what it means.',
275
+ 'Every number can be traced to the code and the source it came from.',
276
+ 'Stage health and the risk to the forecast are visible at a glance.',
277
+ 'A figure in the report is the same figure whoever computes it.',
278
+ ],
279
+ style: [
280
+ 'Plain, direct sentences; the conclusion first.',
281
+ 'Name things by what they are; no marketing adjectives.',
282
+ 'Structured output — headings, short lists, tables for figures — over long prose.',
283
+ ],
284
+ norms: [
285
+ 'Run the analysis in the sandbox and report the result, not the raw data.',
286
+ 'Cite the source of every factual claim.',
287
+ 'Prefer the smallest change, and the simplest explanation, that is correct.',
288
+ 'State the period, the currency and the date of the data on every report.',
289
+ 'Give a rate with its numerator and its denominator.',
290
+ 'Break a total down by region and by segment when the data carries them.',
291
+ ],
292
+ process: [
293
+ 'Load the pipeline data and check it — stages known, amounts positive, dates valid, no duplicate opportunity.',
294
+ 'Compute the totals by stage, the stage conversions and the weighted pipeline.',
295
+ 'Compare with the target and with the previous period, where the data has them.',
296
+ 'Identify the risks — stalled stages, slippage, concentration on a few deals.',
297
+ ],
298
+ architecture: '',
299
+ prompts: [],
300
+ skills: ['events:0.0.1'],
301
+ tools: [],
302
+ mcpServers: [],
303
+ guards: [
304
+ {
305
+ id: 'no-secrets',
306
+ category: 'policy-safety',
307
+ description: 'The output contains no credential, token, API key or password.',
308
+ required: true,
309
+ },
310
+ {
311
+ id: 'totals-reconcile',
312
+ category: 'algorithmic',
313
+ description: 'The totals by stage, by region and by segment each add up to the total pipeline.',
314
+ required: true,
315
+ },
316
+ {
317
+ id: 'definitions-applied',
318
+ category: 'policy-safety',
319
+ description: 'Conversion, weighted pipeline and coverage are computed as this Frame defines them.',
320
+ required: true,
321
+ },
322
+ {
323
+ id: 'data-quality-reported',
324
+ category: 'algorithmic',
325
+ description: 'Rows excluded from a figure, and why, are counted and reported.',
326
+ required: true,
327
+ },
328
+ ],
329
+ };
330
+ export const WEB_RESEARCH_FRAME_0_0_1 = {
331
+ id: 'web-research',
332
+ version: '0.0.1',
333
+ name: 'Web Research Frame',
334
+ description: 'The methodology of research on the open web and on public repositories: which sources count, how recent they have to be, how they are cited, and what a finding has to pass before it is reported.',
335
+ scope: 'role',
336
+ owner: 'Datalayer Research <info@datalayer.io>',
337
+ extends: 'datalayer:0.0.1',
338
+ lineage: ['datalayer'],
339
+ tags: ['research', 'web', 'sources'],
340
+ enabled: true,
341
+ icon: 'globe',
342
+ emoji: '🌐',
343
+ rules: [
344
+ 'Never claim a capability, a tool or a result you have not verified.',
345
+ 'Never put a secret, a credential or a token in an output.',
346
+ 'Say what you did not do and what you could not check, as plainly as what you did.',
347
+ 'Keep personal data out of an output unless the task is about that person and they are its audience.',
348
+ 'Report a claim only with the address of the page or the repository it was read on.',
349
+ 'Never present a search-result snippet as the content of the page; open the page.',
350
+ "Respect a site's terms and its robots policy; do not go around a paywall or a login.",
351
+ 'Say when sources disagree, and report both sides rather than choosing silently.',
352
+ ],
353
+ terminology: {
354
+ Agentspec: 'The declarative YAML specification of an agent.',
355
+ Frame: 'The context work happens in, written down, owned, versioned and inherited.',
356
+ Cog: 'An AI worker you can hold to account — an agent equipped with Frames.',
357
+ Guard: 'A check the output of a piece of work has to pass.',
358
+ Sandbox: 'The isolated environment an agent runs code in, beside the data.',
359
+ 'Primary source': "The party a fact originates from — the vendor's own page, the repository itself, the paper.",
360
+ 'Secondary source': 'A party reporting a primary source — a news article, a blog post, an aggregator.',
361
+ 'Recency window': 'How old a source may be for the question asked; twelve months unless the task says otherwise.',
362
+ },
363
+ goals: [
364
+ 'The reader can act on the output without asking what it means.',
365
+ 'Every number can be traced to the code and the source it came from.',
366
+ 'Each finding rests on at least one primary source.',
367
+ 'The reader can open every source and find the claim there.',
368
+ ],
369
+ style: [
370
+ 'Plain, direct sentences; the conclusion first.',
371
+ 'Name things by what they are; no marketing adjectives.',
372
+ 'Structured output — headings, short lists, tables for figures — over long prose.',
373
+ 'A short summary first, then findings, each with its sources as links.',
374
+ 'Give the date of a source beside it when recency matters.',
375
+ ],
376
+ norms: [
377
+ 'Run the analysis in the sandbox and report the result, not the raw data.',
378
+ 'Cite the source of every factual claim.',
379
+ 'Prefer the smallest change, and the simplest explanation, that is correct.',
380
+ 'Prefer a primary source to a secondary one, and say which a claim rests on.',
381
+ 'Search more than one way before concluding that something does not exist.',
382
+ 'Note the date the research was done.',
383
+ ],
384
+ process: [
385
+ 'Restate the question and what would count as an answer.',
386
+ 'Search, then open and read the most relevant pages and repositories.',
387
+ 'Extract the claims, each with its source and its date.',
388
+ 'Cross-check each important claim against a second, independent source.',
389
+ 'Summarize, with sources cited and disagreements said.',
390
+ ],
391
+ architecture: '',
392
+ prompts: [],
393
+ skills: ['crawl:0.0.1', 'github:0.0.1'],
394
+ tools: [],
395
+ mcpServers: ['tavily:0.0.1'],
396
+ guards: [
397
+ {
398
+ id: 'no-secrets',
399
+ category: 'policy-safety',
400
+ description: 'The output contains no credential, token, API key or password.',
401
+ required: true,
402
+ },
403
+ {
404
+ id: 'sources-cited',
405
+ category: 'source-grounding',
406
+ description: 'Every factual claim in the output carries a link to the page or repository it was read on.',
407
+ required: true,
408
+ },
409
+ {
410
+ id: 'source-supports-claim',
411
+ category: 'source-grounding',
412
+ description: 'Each cited page was opened, and what it says supports the claim made from it.',
413
+ required: true,
414
+ },
415
+ {
416
+ id: 'recency-stated',
417
+ category: 'algorithmic',
418
+ description: 'Every source older than the recency window is marked with its date.',
419
+ required: false,
420
+ },
421
+ ],
422
+ };
423
+ export const FRAME_CATALOGUE = {
424
+ 'board-reporting': BOARD_REPORTING_FRAME_0_0_1,
425
+ 'customer-research': CUSTOMER_RESEARCH_FRAME_0_0_1,
426
+ datalayer: DATALAYER_FRAME_0_0_1,
427
+ 'sales-pipeline': SALES_PIPELINE_FRAME_0_0_1,
428
+ 'web-research': WEB_RESEARCH_FRAME_0_0_1,
429
+ };
430
+ /** The Frame a Cog names, by `id` or `id:version`, or undefined. */
431
+ export function getFrame(frameId) {
432
+ // Own entries only: `constructor` and `toString` are not Frames.
433
+ const own = (id) => Object.prototype.hasOwnProperty.call(FRAME_CATALOGUE, id)
434
+ ? FRAME_CATALOGUE[id]
435
+ : undefined;
436
+ const at = frameId.lastIndexOf(':');
437
+ return (own(frameId) ??
438
+ (at > 0 && frameId.slice(at + 1).includes('.')
439
+ ? own(frameId.slice(0, at))
440
+ : undefined));
441
+ }
442
+ export function listFrames() {
443
+ return Object.values(FRAME_CATALOGUE);
444
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Gate Catalog.
3
+ *
4
+ * Decision points: what happens on what the Guards found.
5
+ * Guards check; Gates decide.
6
+ *
7
+ * This file is AUTO-GENERATED from YAML specifications.
8
+ * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
9
+ */
10
+ import type { GateSpec } from '../types/agentspecs';
11
+ export declare const CONFIGURATION_CHECK_GATE_0_0_1: GateSpec;
12
+ export declare const CONSENSUS_DISAGREEMENT_REVIEW_GATE_0_0_1: GateSpec;
13
+ export declare const LOW_CONFIDENCE_REVIEW_GATE_0_0_1: GateSpec;
14
+ export declare const QUALITY_DRIFT_REVIEW_GATE_0_0_1: GateSpec;
15
+ export declare const RELEASE_APPROVAL_GATE_0_0_1: GateSpec;
16
+ export declare const SENSITIVE_DATA_STOP_GATE_0_0_1: GateSpec;
17
+ export declare const TOOL_VIOLATION_RETRY_GATE_0_0_1: GateSpec;
18
+ export declare const UNSUPPORTED_CLAIMS_REVISION_GATE_0_0_1: GateSpec;
19
+ export declare const GATE_CATALOGUE: Record<string, GateSpec>;
20
+ /** A Gate, by `id` or `id:version`, or undefined. */
21
+ export declare function getGate(ref: string): GateSpec | undefined;
22
+ export declare function listGates(): GateSpec[];
@@ -0,0 +1,177 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export const CONFIGURATION_CHECK_GATE_0_0_1 = {
6
+ id: 'configuration-check',
7
+ version: '0.0.1',
8
+ name: 'Configuration Check',
9
+ 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.',
10
+ stage: 'preflight',
11
+ guards: [
12
+ 'required-frame-guard:0.0.1',
13
+ 'permission-guard:0.0.1',
14
+ 'data-source-authorization-guard:0.0.1',
15
+ ],
16
+ when: 'frames_missing or permission_denied or unauthorized_source',
17
+ then: 'stop_and_escalate',
18
+ otherwise: 'proceed',
19
+ reviewers: ['op-owner'],
20
+ maxRetries: 0,
21
+ enabled: true,
22
+ tags: ['preflight'],
23
+ icon: 'git-branch',
24
+ emoji: '🚦',
25
+ signals: ['frames_missing', 'permission_denied', 'unauthorized_source'],
26
+ };
27
+ export const CONSENSUS_DISAGREEMENT_REVIEW_GATE_0_0_1 = {
28
+ id: 'consensus-disagreement-review',
29
+ version: '0.0.1',
30
+ name: 'Consensus Disagreement Review',
31
+ description: 'Escalates to an expert when independent recomputations disagree on more than a quarter of the key figures.',
32
+ stage: 'post_run',
33
+ guards: ['consensus-guard:0.0.1'],
34
+ when: 'consensus_disagreement > 0.25',
35
+ then: 'expert_review_required',
36
+ otherwise: 'proceed',
37
+ reviewers: ['subject-matter-expert'],
38
+ maxRetries: 0,
39
+ enabled: true,
40
+ tags: ['consensus'],
41
+ icon: 'git-branch',
42
+ emoji: '🚦',
43
+ signals: ['consensus_disagreement'],
44
+ };
45
+ export const LOW_CONFIDENCE_REVIEW_GATE_0_0_1 = {
46
+ id: 'low-confidence-review',
47
+ version: '0.0.1',
48
+ name: 'Low Confidence Review',
49
+ 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.',
50
+ stage: 'post_run',
51
+ guards: ['confidence-guard:0.0.1'],
52
+ when: 'confidence < 0.80',
53
+ then: 'human_review_required',
54
+ otherwise: 'proceed',
55
+ reviewers: ['op-owner'],
56
+ maxRetries: 0,
57
+ enabled: true,
58
+ tags: ['confidence', 'human-in-the-loop'],
59
+ icon: 'git-branch',
60
+ emoji: '🚦',
61
+ signals: ['confidence'],
62
+ };
63
+ export const QUALITY_DRIFT_REVIEW_GATE_0_0_1 = {
64
+ id: 'quality-drift-review',
65
+ version: '0.0.1',
66
+ name: 'Quality Drift Review',
67
+ 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.',
68
+ stage: 'continuous',
69
+ guards: ['regression-guard:0.0.1', 'outcome-guard:0.0.1'],
70
+ when: 'regression_rate > 0.10 or outcome_met == false',
71
+ then: 'expert_review_required',
72
+ otherwise: 'proceed',
73
+ reviewers: ['op-owner', 'subject-matter-expert'],
74
+ maxRetries: 0,
75
+ enabled: true,
76
+ tags: ['drift', 'outcome'],
77
+ icon: 'git-branch',
78
+ emoji: '🚦',
79
+ signals: ['regression_rate', 'outcome_met'],
80
+ };
81
+ export const RELEASE_APPROVAL_GATE_0_0_1 = {
82
+ id: 'release-approval',
83
+ version: '0.0.1',
84
+ name: 'Release Approval',
85
+ 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.",
86
+ stage: 'post_run',
87
+ guards: ['expert-sampling-guard:0.0.1'],
88
+ when: 'always',
89
+ then: 'human_approval_required',
90
+ otherwise: 'stop',
91
+ reviewers: ['op-owner', 'finance'],
92
+ maxRetries: 0,
93
+ enabled: true,
94
+ tags: ['approval', 'human-in-the-loop'],
95
+ icon: 'git-branch',
96
+ emoji: '🚦',
97
+ signals: [],
98
+ };
99
+ export const SENSITIVE_DATA_STOP_GATE_0_0_1 = {
100
+ id: 'sensitive-data-stop',
101
+ version: '0.0.1',
102
+ name: 'Sensitive Data Stop',
103
+ 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.',
104
+ stage: 'in_flight',
105
+ guards: ['sensitive-data-guard:0.0.1'],
106
+ when: 'sensitive_data_detected',
107
+ then: 'stop_and_escalate',
108
+ otherwise: 'proceed',
109
+ reviewers: ['data-protection-officer'],
110
+ maxRetries: 0,
111
+ enabled: true,
112
+ tags: ['privacy'],
113
+ icon: 'git-branch',
114
+ emoji: '🚦',
115
+ signals: ['sensitive_data_detected'],
116
+ };
117
+ export const TOOL_VIOLATION_RETRY_GATE_0_0_1 = {
118
+ id: 'tool-violation-retry',
119
+ version: '0.0.1',
120
+ name: 'Tool Violation Retry',
121
+ 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.',
122
+ stage: 'in_flight',
123
+ guards: ['tool-use-policy-guard:0.0.1'],
124
+ when: 'tool_violation',
125
+ then: 'retry',
126
+ otherwise: 'proceed',
127
+ reviewers: [],
128
+ maxRetries: 2,
129
+ enabled: true,
130
+ tags: ['tools'],
131
+ icon: 'git-branch',
132
+ emoji: '🚦',
133
+ signals: ['tool_violation'],
134
+ };
135
+ export const UNSUPPORTED_CLAIMS_REVISION_GATE_0_0_1 = {
136
+ id: 'unsupported-claims-revision',
137
+ version: '0.0.1',
138
+ name: 'Unsupported Claims Revision',
139
+ 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.',
140
+ stage: 'post_run',
141
+ guards: ['schema-guard:0.0.1', 'source-grounding-guard:0.0.1'],
142
+ when: 'schema_valid == false or unsupported_claims > 0',
143
+ then: 'pause',
144
+ otherwise: 'proceed',
145
+ reviewers: [],
146
+ maxRetries: 0,
147
+ enabled: true,
148
+ tags: ['evidence'],
149
+ icon: 'git-branch',
150
+ emoji: '🚦',
151
+ signals: ['schema_valid', 'unsupported_claims'],
152
+ };
153
+ export const GATE_CATALOGUE = {
154
+ 'configuration-check': CONFIGURATION_CHECK_GATE_0_0_1,
155
+ 'consensus-disagreement-review': CONSENSUS_DISAGREEMENT_REVIEW_GATE_0_0_1,
156
+ 'low-confidence-review': LOW_CONFIDENCE_REVIEW_GATE_0_0_1,
157
+ 'quality-drift-review': QUALITY_DRIFT_REVIEW_GATE_0_0_1,
158
+ 'release-approval': RELEASE_APPROVAL_GATE_0_0_1,
159
+ 'sensitive-data-stop': SENSITIVE_DATA_STOP_GATE_0_0_1,
160
+ 'tool-violation-retry': TOOL_VIOLATION_RETRY_GATE_0_0_1,
161
+ 'unsupported-claims-revision': UNSUPPORTED_CLAIMS_REVISION_GATE_0_0_1,
162
+ };
163
+ /** A Gate, by `id` or `id:version`, or undefined. */
164
+ export function getGate(ref) {
165
+ // Own entries only: `constructor` and `toString` are not Gates.
166
+ const own = (id) => Object.prototype.hasOwnProperty.call(GATE_CATALOGUE, id)
167
+ ? GATE_CATALOGUE[id]
168
+ : undefined;
169
+ const at = ref.lastIndexOf(':');
170
+ return (own(ref) ??
171
+ (at > 0 && ref.slice(at + 1).includes('.')
172
+ ? own(ref.slice(0, at))
173
+ : undefined));
174
+ }
175
+ export function listGates() {
176
+ return Object.values(GATE_CATALOGUE);
177
+ }