@datalayer/agent-runtimes 1.5.38 → 1.5.39
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.
- package/lib/specs/index.d.ts +1 -0
- package/lib/specs/index.js +1 -0
- package/lib/specs/standards.d.ts +18 -0
- package/lib/specs/standards.js +6843 -0
- package/lib/types/agentspecs.d.ts +65 -0
- package/package.json +1 -1
- package/scripts/codegen/generate_standards.py +232 -0
|
@@ -269,6 +269,71 @@ export interface PolicySpec {
|
|
|
269
269
|
};
|
|
270
270
|
};
|
|
271
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* One control of a standard, as its spec carries it (`agentspecs/standards`).
|
|
274
|
+
*/
|
|
275
|
+
export interface StandardControl {
|
|
276
|
+
id: string;
|
|
277
|
+
title: string;
|
|
278
|
+
domain: string;
|
|
279
|
+
application: 'mandatory' | 'optional';
|
|
280
|
+
retired: boolean;
|
|
281
|
+
retired_in?: string | null;
|
|
282
|
+
url?: string;
|
|
283
|
+
cadence_months?: number | null;
|
|
284
|
+
type?: 'preventative' | 'detective' | null;
|
|
285
|
+
summary?: string;
|
|
286
|
+
keywords?: string[];
|
|
287
|
+
capabilities?: string[];
|
|
288
|
+
activities?: Array<{
|
|
289
|
+
required: 'core' | 'supplemental';
|
|
290
|
+
activity: string;
|
|
291
|
+
}>;
|
|
292
|
+
evidence?: Array<{
|
|
293
|
+
id: string;
|
|
294
|
+
kind: 'documentation' | 'config' | 'logs' | 'evals' | 'report' | 'demonstration' | 'retired';
|
|
295
|
+
title: string;
|
|
296
|
+
required: 'core' | 'supplemental';
|
|
297
|
+
category?: string;
|
|
298
|
+
locations?: string[];
|
|
299
|
+
description?: string;
|
|
300
|
+
}>;
|
|
301
|
+
/** Framework id → the references of that framework this control maps to. */
|
|
302
|
+
crosswalks?: Record<string, string[]>;
|
|
303
|
+
/** For a standard that maps to another: that standard's controls covering this one, and how far. */
|
|
304
|
+
covered_by?: string[] | null;
|
|
305
|
+
coverage?: 'full' | 'partial' | 'none' | null;
|
|
306
|
+
coverage_note?: string;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* A standard a conformance report answers (`agentspecs/standards`, SHIELD.md
|
|
310
|
+
* SH-60, §6.9): its version, domains and controls, carried whole.
|
|
311
|
+
*/
|
|
312
|
+
export interface StandardSpec {
|
|
313
|
+
id: string;
|
|
314
|
+
/** The standard's own version (2026.4, 2023). */
|
|
315
|
+
version: string;
|
|
316
|
+
name: string;
|
|
317
|
+
description: string;
|
|
318
|
+
enabled: boolean;
|
|
319
|
+
tags: string[];
|
|
320
|
+
publishedBy: string;
|
|
321
|
+
url: string;
|
|
322
|
+
releasedOn: string;
|
|
323
|
+
nextReleaseOn: string | null;
|
|
324
|
+
/** The day the spec was read from the published pages (decision 16). */
|
|
325
|
+
readOn: string;
|
|
326
|
+
certificateValidMonths: number;
|
|
327
|
+
mapsTo: string | null;
|
|
328
|
+
evidenceKinds: Record<string, string>;
|
|
329
|
+
frameworks: Record<string, string>;
|
|
330
|
+
domains: Array<{
|
|
331
|
+
id: string;
|
|
332
|
+
name: string;
|
|
333
|
+
url?: string;
|
|
334
|
+
}>;
|
|
335
|
+
controls: StandardControl[];
|
|
336
|
+
}
|
|
272
337
|
export interface HarnessSpec {
|
|
273
338
|
/** What `harness:` names (e.g. 'claude-code'). */
|
|
274
339
|
id: string;
|
package/package.json
CHANGED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
# Distributed under the terms of the Modified BSD License.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Generate Python and TypeScript code from the YAML standard specifications.
|
|
7
|
+
|
|
8
|
+
One YAML per standard under ``agentspecs/standards`` (SHIELD.md SH-60, §6.9):
|
|
9
|
+
its version, domains and controls, each control with its evidence items,
|
|
10
|
+
cadence and crosswalks. The catalogue is carried whole: the Studio's
|
|
11
|
+
conformance screens read a control's title, status words and crosswalks
|
|
12
|
+
from it, never from a hand-written list.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
python generate_standards.py \\
|
|
16
|
+
--specs-dir agentspecs/agentspecs/standards \\
|
|
17
|
+
--python-output agent_runtimes/specs/standards.py \\
|
|
18
|
+
--typescript-output src/specs/standards.ts
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
import yaml
|
|
27
|
+
from versioning import ensure_spec_version
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def load_standard_specs(specs_dir: Path) -> list[dict[str, Any]]:
|
|
31
|
+
"""Every standard spec of a directory, each named for its id."""
|
|
32
|
+
specs = []
|
|
33
|
+
for yaml_file in sorted(specs_dir.glob("*.yaml")):
|
|
34
|
+
spec = yaml.safe_load(yaml_file.read_text()) or {}
|
|
35
|
+
if spec.get("id") != yaml_file.stem:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"{yaml_file.name}: the file is named for {yaml_file.stem!r}, the spec says {spec.get('id')!r}"
|
|
38
|
+
)
|
|
39
|
+
if not isinstance(spec.get("controls"), list) or not spec["controls"]:
|
|
40
|
+
raise ValueError(f"{yaml_file.name}: a standard lists its controls")
|
|
41
|
+
# A standard's version is its own (2026.4, 2023): the generated symbol takes it as written.
|
|
42
|
+
spec["spec_version"] = str(spec.get("version"))
|
|
43
|
+
ensure_spec_version(spec, default="0.0.1")
|
|
44
|
+
specs.append(spec)
|
|
45
|
+
return specs
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _const(spec: dict[str, Any]) -> str:
|
|
49
|
+
return spec["id"].replace("-", "_").replace(".", "_").upper() + "_STANDARD"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _s(value: Any) -> str:
|
|
53
|
+
return json.dumps(" ".join(str(value or "").split()), ensure_ascii=False)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _dates(value: Any) -> str:
|
|
57
|
+
return _s(value.isoformat() if hasattr(value, "isoformat") else value)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _py_literal(value: Any, indent: int = 8) -> str:
|
|
61
|
+
text = json.dumps(value, ensure_ascii=False, indent=indent, default=str)
|
|
62
|
+
return (
|
|
63
|
+
text.replace(": true", ": True")
|
|
64
|
+
.replace(": false", ": False")
|
|
65
|
+
.replace(": null", ": None")
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
70
|
+
lines = [
|
|
71
|
+
"# Copyright (c) 2025-2026 Datalayer, Inc.",
|
|
72
|
+
"# Distributed under the terms of the Modified BSD License.",
|
|
73
|
+
'"""',
|
|
74
|
+
"Standard Catalog.",
|
|
75
|
+
"",
|
|
76
|
+
"The standards a conformance report answers (SHIELD.md SH-60, §6.9): each a",
|
|
77
|
+
"catalogue entry carrying the standard's domains and controls whole.",
|
|
78
|
+
"",
|
|
79
|
+
"This file is AUTO-GENERATED from YAML specifications.",
|
|
80
|
+
"DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
|
|
81
|
+
'"""',
|
|
82
|
+
"",
|
|
83
|
+
"from typing import Any, Dict, List, Optional",
|
|
84
|
+
"",
|
|
85
|
+
"from agent_runtimes.types import StandardSpec",
|
|
86
|
+
]
|
|
87
|
+
for spec in specs:
|
|
88
|
+
lines += [
|
|
89
|
+
"",
|
|
90
|
+
f"{_const(spec)} = StandardSpec(",
|
|
91
|
+
f" id={_s(spec['id'])},",
|
|
92
|
+
f" version={_s(spec['spec_version'])},",
|
|
93
|
+
f" name={_s(spec['name'])},",
|
|
94
|
+
f" description={_s(spec.get('description'))},",
|
|
95
|
+
f" enabled={bool(spec.get('enabled', True))},",
|
|
96
|
+
f" tags={json.dumps(list(spec.get('tags') or []))},",
|
|
97
|
+
f" published_by={_s(spec.get('published_by'))},",
|
|
98
|
+
f" url={_s(spec.get('url'))},",
|
|
99
|
+
f" released_on={_dates(spec.get('released_on'))},",
|
|
100
|
+
f" next_release_on={_dates(spec.get('next_release_on')) if spec.get('next_release_on') else None},",
|
|
101
|
+
f" read_on={_dates(spec.get('read_on'))},",
|
|
102
|
+
f" certificate_valid_months={int(spec.get('certificate_valid_months') or 12)},",
|
|
103
|
+
f" maps_to={_s(spec['maps_to']) if spec.get('maps_to') else None},",
|
|
104
|
+
f" evidence_kinds={_py_literal(spec.get('evidence_kinds') or {})},",
|
|
105
|
+
f" frameworks={_py_literal(spec.get('frameworks') or {})},",
|
|
106
|
+
f" domains={_py_literal(spec.get('domains') or [])},",
|
|
107
|
+
f" controls={_py_literal(spec.get('controls') or [])},",
|
|
108
|
+
")",
|
|
109
|
+
]
|
|
110
|
+
lines += [
|
|
111
|
+
"",
|
|
112
|
+
"",
|
|
113
|
+
"STANDARD_CATALOGUE: Dict[str, StandardSpec] = {",
|
|
114
|
+
*[f" {_s(spec['id'])}: {_const(spec)}," for spec in specs],
|
|
115
|
+
"}",
|
|
116
|
+
"",
|
|
117
|
+
"",
|
|
118
|
+
"def get_standard(standard_id: str) -> Optional[StandardSpec]:",
|
|
119
|
+
' """A standard by id, or None."""',
|
|
120
|
+
" return STANDARD_CATALOGUE.get(standard_id)",
|
|
121
|
+
"",
|
|
122
|
+
"",
|
|
123
|
+
"def list_standards() -> List[StandardSpec]:",
|
|
124
|
+
' """Every standard of the catalogue."""',
|
|
125
|
+
" return list(STANDARD_CATALOGUE.values())",
|
|
126
|
+
"",
|
|
127
|
+
"",
|
|
128
|
+
"def control_of(standard_id: str, control_id: str) -> Optional[Dict[str, Any]]:",
|
|
129
|
+
' """One control of a standard, as the spec carries it, or None."""',
|
|
130
|
+
" spec = STANDARD_CATALOGUE.get(standard_id)",
|
|
131
|
+
" if spec is None:",
|
|
132
|
+
" return None",
|
|
133
|
+
' return next((dict(c) for c in spec.controls if c.get("id") == control_id), None)',
|
|
134
|
+
"",
|
|
135
|
+
]
|
|
136
|
+
return "\n".join(lines)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _t(value: Any) -> str:
|
|
140
|
+
return json.dumps(" ".join(str(value or "").split()), ensure_ascii=False)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _ts_value(value: Any, indent: int = 2) -> str:
|
|
144
|
+
text = json.dumps(value, ensure_ascii=False, indent=2, default=str)
|
|
145
|
+
pad = " " * indent
|
|
146
|
+
return "\n".join(
|
|
147
|
+
pad + line if i else line for i, line in enumerate(text.splitlines())
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
152
|
+
lines = [
|
|
153
|
+
"/*",
|
|
154
|
+
" * Copyright (c) 2025-2026 Datalayer, Inc.",
|
|
155
|
+
" * Distributed under the terms of the Modified BSD License.",
|
|
156
|
+
" */",
|
|
157
|
+
"",
|
|
158
|
+
"/**",
|
|
159
|
+
" * Standard Catalog.",
|
|
160
|
+
" *",
|
|
161
|
+
" * The standards a conformance report answers (SHIELD.md SH-60, §6.9).",
|
|
162
|
+
" *",
|
|
163
|
+
" * This file is AUTO-GENERATED from YAML specifications.",
|
|
164
|
+
" * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
|
|
165
|
+
" */",
|
|
166
|
+
"",
|
|
167
|
+
"import type { StandardControl, StandardSpec } from '../types/agentspecs';",
|
|
168
|
+
]
|
|
169
|
+
for spec in specs:
|
|
170
|
+
lines += [
|
|
171
|
+
"",
|
|
172
|
+
f"export const {_const(spec)}: StandardSpec = {{",
|
|
173
|
+
f" id: {_t(spec['id'])},",
|
|
174
|
+
f" version: {_t(spec['spec_version'])},",
|
|
175
|
+
f" name: {_t(spec['name'])},",
|
|
176
|
+
f" description: {_t(spec.get('description'))},",
|
|
177
|
+
f" enabled: {'true' if spec.get('enabled', True) else 'false'},",
|
|
178
|
+
f" tags: {json.dumps(list(spec.get('tags') or []))},",
|
|
179
|
+
f" publishedBy: {_t(spec.get('published_by'))},",
|
|
180
|
+
f" url: {_t(spec.get('url'))},",
|
|
181
|
+
f" releasedOn: {_dates(spec.get('released_on'))},",
|
|
182
|
+
f" nextReleaseOn: {_dates(spec.get('next_release_on')) if spec.get('next_release_on') else 'null'},",
|
|
183
|
+
f" readOn: {_dates(spec.get('read_on'))},",
|
|
184
|
+
f" certificateValidMonths: {int(spec.get('certificate_valid_months') or 12)},",
|
|
185
|
+
f" mapsTo: {_t(spec['maps_to']) if spec.get('maps_to') else 'null'},",
|
|
186
|
+
f" evidenceKinds: {_ts_value(spec.get('evidence_kinds') or {})},",
|
|
187
|
+
f" frameworks: {_ts_value(spec.get('frameworks') or {})},",
|
|
188
|
+
f" domains: {_ts_value(spec.get('domains') or [])},",
|
|
189
|
+
f" controls: {_ts_value(spec.get('controls') or [])} as StandardControl[],",
|
|
190
|
+
"};",
|
|
191
|
+
]
|
|
192
|
+
lines += [
|
|
193
|
+
"",
|
|
194
|
+
"export const STANDARD_CATALOGUE: Record<string, StandardSpec> = {",
|
|
195
|
+
*[f" {_t(spec['id'])}: {_const(spec)}," for spec in specs],
|
|
196
|
+
"};",
|
|
197
|
+
"",
|
|
198
|
+
"/** A standard by id. */",
|
|
199
|
+
"export function getStandard(standardId: string): StandardSpec | undefined {",
|
|
200
|
+
" return STANDARD_CATALOGUE[standardId];",
|
|
201
|
+
"}",
|
|
202
|
+
"",
|
|
203
|
+
"/** Every standard of the catalogue. */",
|
|
204
|
+
"export function listStandardSpecs(): StandardSpec[] {",
|
|
205
|
+
" return Object.values(STANDARD_CATALOGUE);",
|
|
206
|
+
"}",
|
|
207
|
+
"",
|
|
208
|
+
"/** One control of a standard, as the spec carries it. */",
|
|
209
|
+
"export function standardControl(standardId: string, controlId: string): StandardControl | undefined {",
|
|
210
|
+
" return STANDARD_CATALOGUE[standardId]?.controls.find(control => control.id === controlId);",
|
|
211
|
+
"}",
|
|
212
|
+
"",
|
|
213
|
+
]
|
|
214
|
+
return "\n".join(lines)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def main() -> None:
|
|
218
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
219
|
+
parser.add_argument("--specs-dir", type=Path, required=True)
|
|
220
|
+
parser.add_argument("--python-output", type=Path, required=True)
|
|
221
|
+
parser.add_argument("--typescript-output", type=Path, required=True)
|
|
222
|
+
args = parser.parse_args()
|
|
223
|
+
specs = load_standard_specs(args.specs_dir)
|
|
224
|
+
args.python_output.write_text(generate_python_code(specs))
|
|
225
|
+
args.typescript_output.write_text(generate_typescript_code(specs))
|
|
226
|
+
print(
|
|
227
|
+
f"Generated {len(specs)} standards: {args.python_output}, {args.typescript_output}"
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
if __name__ == "__main__":
|
|
232
|
+
main()
|