permea-core 0.1.0__py3-none-any.whl

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 (94) hide show
  1. permea_core/__init__.py +9 -0
  2. permea_core/acquisition/__init__.py +39 -0
  3. permea_core/acquisition/manifests.py +470 -0
  4. permea_core/benchmarks/__init__.py +73 -0
  5. permea_core/benchmarks/cards.py +226 -0
  6. permea_core/benchmarks/evidence_cards.py +201 -0
  7. permea_core/benchmarks/output_package.py +212 -0
  8. permea_core/benchmarks/registry.py +246 -0
  9. permea_core/cli/__init__.py +5 -0
  10. permea_core/cli/_format.py +49 -0
  11. permea_core/cli/bench.py +117 -0
  12. permea_core/cli/main.py +35 -0
  13. permea_core/cluster/__init__.py +27 -0
  14. permea_core/cluster/identity.py +248 -0
  15. permea_core/consistency/__init__.py +1 -0
  16. permea_core/consistency/artifacts.py +264 -0
  17. permea_core/contracts/__init__.py +8 -0
  18. permea_core/contracts/warnings.py +297 -0
  19. permea_core/data/__init__.py +5 -0
  20. permea_core/data/contracts.py +43 -0
  21. permea_core/datasets/__init__.py +41 -0
  22. permea_core/datasets/cards.py +457 -0
  23. permea_core/datasets/load.py +30 -0
  24. permea_core/demo/__init__.py +1 -0
  25. permea_core/demo/packet.py +291 -0
  26. permea_core/diagnose/__init__.py +35 -0
  27. permea_core/diagnose/rules.py +293 -0
  28. permea_core/dry_run/__init__.py +15 -0
  29. permea_core/dry_run/orchestrator.py +269 -0
  30. permea_core/eval/__init__.py +5 -0
  31. permea_core/eval/bootstrap.py +71 -0
  32. permea_core/eval/engine.py +180 -0
  33. permea_core/eval/metrics.py +43 -0
  34. permea_core/eval/run.py +234 -0
  35. permea_core/evaluation/__init__.py +2 -0
  36. permea_core/evaluation/bundle.py +335 -0
  37. permea_core/evidence/__init__.py +1 -0
  38. permea_core/evidence/matrix.py +349 -0
  39. permea_core/generation/__init__.py +13 -0
  40. permea_core/generation/artifacts.py +96 -0
  41. permea_core/index/__init__.py +15 -0
  42. permea_core/index/artifact_index.py +224 -0
  43. permea_core/provenance/__init__.py +5 -0
  44. permea_core/provenance/run_manifest.py +35 -0
  45. permea_core/represent/__init__.py +19 -0
  46. permea_core/represent/physchem.py +61 -0
  47. permea_core/reproducibility/bundle.py +269 -0
  48. permea_core/review_packets/__init__.py +19 -0
  49. permea_core/review_packets/bundle_completeness.py +117 -0
  50. permea_core/review_packets/coverage.py +102 -0
  51. permea_core/review_packets/loop_readiness.py +152 -0
  52. permea_core/review_packets/packets.py +483 -0
  53. permea_core/runners/__init__.py +5 -0
  54. permea_core/runners/base.py +34 -0
  55. permea_core/runs/__init__.py +1 -0
  56. permea_core/runs/manifests.py +435 -0
  57. permea_core/sources/__init__.py +27 -0
  58. permea_core/sources/registry.py +233 -0
  59. permea_core/specs/__init__.py +2 -0
  60. permea_core/specs/registry.py +119 -0
  61. permea_core/surface/evidence_surface.py +276 -0
  62. permea_core/validation/__init__.py +21 -0
  63. permea_core/validation/artifact_validator.py +585 -0
  64. permea_core/validation/artifacts.py +104 -0
  65. permea_core-0.1.0.dist-info/METADATA +574 -0
  66. permea_core-0.1.0.dist-info/RECORD +94 -0
  67. permea_core-0.1.0.dist-info/WHEEL +5 -0
  68. permea_core-0.1.0.dist-info/entry_points.txt +3 -0
  69. permea_core-0.1.0.dist-info/licenses/LICENSE +201 -0
  70. permea_core-0.1.0.dist-info/top_level.txt +3 -0
  71. permea_explain/__init__.py +27 -0
  72. permea_explain/extract.py +1304 -0
  73. permea_explain/extract_prompt.py +111 -0
  74. permea_explain/guardrails.py +267 -0
  75. permea_explain/narrate.py +74 -0
  76. permea_explain/prompt.py +84 -0
  77. permea_explain/providers/__init__.py +37 -0
  78. permea_explain/providers/anthropic.py +29 -0
  79. permea_explain/providers/base.py +46 -0
  80. permea_explain/providers/configured.py +167 -0
  81. permea_explain/providers/openai.py +29 -0
  82. permea_explain/schemas/extract.schema.json +490 -0
  83. permea_explain/schemas/label_schema.schema.json +160 -0
  84. permea_explain/source.py +48 -0
  85. permea_explain/violations.py +145 -0
  86. permea_ui/__init__.py +12 -0
  87. permea_ui/__main__.py +79 -0
  88. permea_ui/app.py +223 -0
  89. permea_ui/fixtures.py +106 -0
  90. permea_ui/jobs.py +90 -0
  91. permea_ui/runner.py +234 -0
  92. permea_ui/static/app.js +294 -0
  93. permea_ui/static/index.html +88 -0
  94. permea_ui/static/style.css +208 -0
@@ -0,0 +1,9 @@
1
+ """Permea Core package."""
2
+
3
+ __all__ = [
4
+ "benchmarks",
5
+ "data",
6
+ "eval",
7
+ "provenance",
8
+ "runners",
9
+ ]
@@ -0,0 +1,39 @@
1
+ """Acquisition manifest validation and generation surfaces for Permea Core."""
2
+
3
+ from .manifests import (
4
+ ALLOWED_ACQUISITION_MODES,
5
+ ALLOWED_ACQUISITION_STATUSES,
6
+ ALLOWED_REDISTRIBUTION_STATUSES,
7
+ DEFAULT_ACQUISITION_MANIFEST_DIR,
8
+ DEFAULT_GENERATED_ACQUISITION_MANIFEST_DIR,
9
+ REQUIRED_ACQUISITION_MANIFEST_FIELDS,
10
+ AcquisitionManifestBatchResult,
11
+ AcquisitionManifestGenerationResult,
12
+ AcquisitionManifestValidationError,
13
+ AcquisitionManifestValidationResult,
14
+ generate_acquisition_manifest_file,
15
+ generate_acquisition_manifests,
16
+ load_acquisition_manifest_yaml,
17
+ render_acquisition_manifest,
18
+ validate_acquisition_manifest,
19
+ validate_acquisition_manifest_file,
20
+ )
21
+
22
+ __all__ = [
23
+ "ALLOWED_ACQUISITION_MODES",
24
+ "ALLOWED_ACQUISITION_STATUSES",
25
+ "ALLOWED_REDISTRIBUTION_STATUSES",
26
+ "DEFAULT_ACQUISITION_MANIFEST_DIR",
27
+ "DEFAULT_GENERATED_ACQUISITION_MANIFEST_DIR",
28
+ "REQUIRED_ACQUISITION_MANIFEST_FIELDS",
29
+ "AcquisitionManifestBatchResult",
30
+ "AcquisitionManifestGenerationResult",
31
+ "AcquisitionManifestValidationError",
32
+ "AcquisitionManifestValidationResult",
33
+ "generate_acquisition_manifest_file",
34
+ "generate_acquisition_manifests",
35
+ "load_acquisition_manifest_yaml",
36
+ "render_acquisition_manifest",
37
+ "validate_acquisition_manifest",
38
+ "validate_acquisition_manifest_file",
39
+ ]
@@ -0,0 +1,470 @@
1
+ """Acquisition manifest YAML validation and Markdown generation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ try:
10
+ import yaml
11
+ except ImportError: # pragma: no cover - exercised only without PyYAML installed.
12
+ yaml = None # type: ignore[assignment]
13
+
14
+
15
+ DEFAULT_ACQUISITION_MANIFEST_DIR = Path("acquisition_manifests")
16
+ DEFAULT_GENERATED_ACQUISITION_MANIFEST_DIR = Path(
17
+ "docs/examples/generated/acquisition_manifests"
18
+ )
19
+
20
+ REQUIRED_ACQUISITION_MANIFEST_FIELDS = frozenset(
21
+ {
22
+ "manifest_id",
23
+ "dataset_id",
24
+ "source_ids",
25
+ "benchmark_ids",
26
+ "acquisition_mode",
27
+ "acquisition_status",
28
+ "redistribution_status",
29
+ "expected_local_outputs",
30
+ "provenance_requirements",
31
+ "license_review_required",
32
+ "manual_review_required",
33
+ "failure_modes",
34
+ "fallback_strategy",
35
+ "claim_boundary",
36
+ "next_action",
37
+ }
38
+ )
39
+
40
+ ALLOWED_ACQUISITION_MODES = frozenset(
41
+ {
42
+ "manual-source-card",
43
+ "public-download-to-verify",
44
+ "api-metadata-to-verify",
45
+ "literature-metadata",
46
+ "no-redistribution-source-card-only",
47
+ }
48
+ )
49
+
50
+ ALLOWED_ACQUISITION_STATUSES = frozenset(
51
+ {
52
+ "source-carded",
53
+ "access-to-verify",
54
+ "license-to-verify",
55
+ "acquisition-planned",
56
+ "acquisition-script-planned",
57
+ "no-redistribution-source-card-only",
58
+ }
59
+ )
60
+
61
+ ALLOWED_REDISTRIBUTION_STATUSES = frozenset(
62
+ {
63
+ "not-reviewed",
64
+ "not-confirmed",
65
+ "no-redistribution",
66
+ "metadata-only",
67
+ "redistribution-to-verify",
68
+ }
69
+ )
70
+
71
+ NON_CLAIMS = (
72
+ "no dataset downloaded",
73
+ "no acquisition executed",
74
+ "no redistribution rights confirmed",
75
+ "no wet-lab validation by Permea",
76
+ )
77
+
78
+
79
+ @dataclass(frozen=True, slots=True)
80
+ class AcquisitionManifestValidationError:
81
+ """Structured validation error for one acquisition manifest."""
82
+
83
+ entry: str
84
+ field: str
85
+ message: str
86
+
87
+
88
+ @dataclass(frozen=True, slots=True)
89
+ class AcquisitionManifestValidationResult:
90
+ """Validation outcome for one acquisition manifest YAML file."""
91
+
92
+ path: Path
93
+ manifest_id: str
94
+ errors: tuple[AcquisitionManifestValidationError, ...] = field(default_factory=tuple)
95
+
96
+ @property
97
+ def passed(self) -> bool:
98
+ """Return True when the acquisition manifest has no validation errors."""
99
+ return not self.errors
100
+
101
+
102
+ @dataclass(frozen=True, slots=True)
103
+ class AcquisitionManifestGenerationResult:
104
+ """Structured result for one generated acquisition manifest file."""
105
+
106
+ input_path: Path
107
+ output_path: Path
108
+ manifest_id: str
109
+ passed: bool
110
+ message: str
111
+
112
+
113
+ @dataclass(frozen=True, slots=True)
114
+ class AcquisitionManifestBatchResult:
115
+ """Structured result for generating multiple acquisition manifest files."""
116
+
117
+ input_dir: Path
118
+ output_dir: Path
119
+ generated: tuple[AcquisitionManifestGenerationResult, ...]
120
+ passed: bool
121
+ message: str
122
+
123
+
124
+ def load_acquisition_manifest_yaml(path: str | Path) -> Any:
125
+ """Load a local acquisition manifest YAML file."""
126
+ if yaml is None:
127
+ raise RuntimeError(
128
+ "PyYAML is required to validate acquisition manifest YAML files. "
129
+ "Install PyYAML or run in the project environment that provides it."
130
+ )
131
+
132
+ manifest_path = Path(path)
133
+ with manifest_path.open("r", encoding="utf-8") as file:
134
+ return yaml.safe_load(file)
135
+
136
+
137
+ def validate_acquisition_manifest(
138
+ manifest: dict[str, Any],
139
+ ) -> list[AcquisitionManifestValidationError]:
140
+ """Validate one acquisition manifest mapping and return structured errors."""
141
+ name = _entry_name(manifest)
142
+ errors: list[AcquisitionManifestValidationError] = []
143
+
144
+ missing = sorted(REQUIRED_ACQUISITION_MANIFEST_FIELDS.difference(manifest))
145
+ for field_name in missing:
146
+ errors.append(
147
+ AcquisitionManifestValidationError(
148
+ entry=name,
149
+ field=field_name,
150
+ message="Required field is missing.",
151
+ )
152
+ )
153
+
154
+ _validate_enum(
155
+ errors=errors,
156
+ entry=name,
157
+ field="acquisition_mode",
158
+ value=manifest.get("acquisition_mode"),
159
+ allowed=ALLOWED_ACQUISITION_MODES,
160
+ )
161
+ _validate_enum(
162
+ errors=errors,
163
+ entry=name,
164
+ field="acquisition_status",
165
+ value=manifest.get("acquisition_status"),
166
+ allowed=ALLOWED_ACQUISITION_STATUSES,
167
+ )
168
+ _validate_enum(
169
+ errors=errors,
170
+ entry=name,
171
+ field="redistribution_status",
172
+ value=manifest.get("redistribution_status"),
173
+ allowed=ALLOWED_REDISTRIBUTION_STATUSES,
174
+ )
175
+
176
+ for field_name in (
177
+ "source_ids",
178
+ "benchmark_ids",
179
+ "expected_local_outputs",
180
+ "provenance_requirements",
181
+ "failure_modes",
182
+ "fallback_strategy",
183
+ ):
184
+ value = manifest.get(field_name)
185
+ if value is not None and not isinstance(value, list):
186
+ errors.append(
187
+ AcquisitionManifestValidationError(
188
+ entry=name,
189
+ field=field_name,
190
+ message=f"{field_name} must be a list.",
191
+ )
192
+ )
193
+
194
+ for field_name in ("license_review_required", "manual_review_required"):
195
+ value = manifest.get(field_name)
196
+ if value is not None and not isinstance(value, bool):
197
+ errors.append(
198
+ AcquisitionManifestValidationError(
199
+ entry=name,
200
+ field=field_name,
201
+ message=f"{field_name} must be a boolean.",
202
+ )
203
+ )
204
+
205
+ return errors
206
+
207
+
208
+ def validate_acquisition_manifest_file(
209
+ path: str | Path,
210
+ ) -> AcquisitionManifestValidationResult:
211
+ """Validate one acquisition manifest YAML file."""
212
+ manifest_path = Path(path)
213
+ try:
214
+ payload = load_acquisition_manifest_yaml(manifest_path)
215
+ except Exception as exc: # noqa: BLE001 - CLI should report load failures clearly.
216
+ return AcquisitionManifestValidationResult(
217
+ path=manifest_path,
218
+ manifest_id="<invalid>",
219
+ errors=(
220
+ AcquisitionManifestValidationError(
221
+ entry="<file>",
222
+ field="<load>",
223
+ message=str(exc),
224
+ ),
225
+ ),
226
+ )
227
+
228
+ if not isinstance(payload, dict):
229
+ return AcquisitionManifestValidationResult(
230
+ path=manifest_path,
231
+ manifest_id="<invalid>",
232
+ errors=(
233
+ AcquisitionManifestValidationError(
234
+ entry="<file>",
235
+ field="<payload>",
236
+ message="Acquisition manifest YAML must contain one mapping.",
237
+ ),
238
+ ),
239
+ )
240
+
241
+ return AcquisitionManifestValidationResult(
242
+ path=manifest_path,
243
+ manifest_id=_entry_name(payload),
244
+ errors=tuple(validate_acquisition_manifest(payload)),
245
+ )
246
+
247
+
248
+ def render_acquisition_manifest(manifest: dict[str, Any]) -> str:
249
+ """Render one validated acquisition manifest as deterministic Markdown."""
250
+ manifest_id = _required_string(manifest, "manifest_id")
251
+ dataset_id = _required_string(manifest, "dataset_id")
252
+
253
+ sections = [
254
+ f"# Acquisition Manifest: {manifest_id}",
255
+ "",
256
+ "> Generated from Permea acquisition-manifest metadata. This public-safe example records planning metadata only: no dataset downloaded, no acquisition executed, no redistribution rights confirmed, and no wet-lab validation by Permea.",
257
+ "",
258
+ "## Manifest ID",
259
+ "",
260
+ manifest_id,
261
+ "",
262
+ "## Dataset ID",
263
+ "",
264
+ dataset_id,
265
+ "",
266
+ "## Source IDs",
267
+ "",
268
+ _render_list(manifest.get("source_ids")),
269
+ "",
270
+ "## Benchmark IDs",
271
+ "",
272
+ _render_list(manifest.get("benchmark_ids")),
273
+ "",
274
+ "## Acquisition Mode",
275
+ "",
276
+ _required_string(manifest, "acquisition_mode"),
277
+ "",
278
+ "## Acquisition Status",
279
+ "",
280
+ _required_string(manifest, "acquisition_status"),
281
+ "",
282
+ "## Redistribution Status",
283
+ "",
284
+ _required_string(manifest, "redistribution_status"),
285
+ "",
286
+ "## Expected Local Outputs",
287
+ "",
288
+ _render_list(manifest.get("expected_local_outputs")),
289
+ "",
290
+ "## Provenance Requirements",
291
+ "",
292
+ _render_list(manifest.get("provenance_requirements")),
293
+ "",
294
+ "## Review Requirements",
295
+ "",
296
+ f"- license_review_required: {manifest.get('license_review_required')}",
297
+ f"- manual_review_required: {manifest.get('manual_review_required')}",
298
+ "",
299
+ "## Failure Modes",
300
+ "",
301
+ _render_list(manifest.get("failure_modes")),
302
+ "",
303
+ "## Fallback Strategy",
304
+ "",
305
+ _render_list(manifest.get("fallback_strategy")),
306
+ "",
307
+ "## Explicit Non-Claims",
308
+ "",
309
+ _render_list(list(NON_CLAIMS)),
310
+ "",
311
+ "## Claim Boundary",
312
+ "",
313
+ _required_string(manifest, "claim_boundary"),
314
+ "",
315
+ "## Next Action",
316
+ "",
317
+ _required_string(manifest, "next_action"),
318
+ "",
319
+ ]
320
+ return "\n".join(sections)
321
+
322
+
323
+ def generate_acquisition_manifest_file(
324
+ input_path: str | Path,
325
+ output_path: str | Path,
326
+ ) -> AcquisitionManifestGenerationResult:
327
+ """Validate one acquisition manifest YAML file and write its Markdown."""
328
+ manifest_path = Path(input_path)
329
+ output = Path(output_path)
330
+
331
+ validation = validate_acquisition_manifest_file(manifest_path)
332
+ if not validation.passed:
333
+ return AcquisitionManifestGenerationResult(
334
+ input_path=manifest_path,
335
+ output_path=output,
336
+ manifest_id=validation.manifest_id,
337
+ passed=False,
338
+ message=_format_validation_failure(validation.errors),
339
+ )
340
+
341
+ payload = load_acquisition_manifest_yaml(manifest_path)
342
+ if not isinstance(payload, dict):
343
+ return AcquisitionManifestGenerationResult(
344
+ input_path=manifest_path,
345
+ output_path=output,
346
+ manifest_id="<invalid>",
347
+ passed=False,
348
+ message="Acquisition manifest YAML must contain one mapping.",
349
+ )
350
+
351
+ output.parent.mkdir(parents=True, exist_ok=True)
352
+ output.write_text(render_acquisition_manifest(payload), encoding="utf-8")
353
+ return AcquisitionManifestGenerationResult(
354
+ input_path=manifest_path,
355
+ output_path=output,
356
+ manifest_id=_required_string(payload, "manifest_id"),
357
+ passed=True,
358
+ message="Generated acquisition manifest.",
359
+ )
360
+
361
+
362
+ def generate_acquisition_manifests(
363
+ input_dir: str | Path,
364
+ output_dir: str | Path,
365
+ ) -> AcquisitionManifestBatchResult:
366
+ """Generate Markdown manifests for every YAML manifest in an input directory."""
367
+ source_dir = Path(input_dir)
368
+ destination = Path(output_dir)
369
+ results: list[AcquisitionManifestGenerationResult] = []
370
+
371
+ for manifest_path in sorted(source_dir.glob("*.yaml")):
372
+ payload = load_acquisition_manifest_yaml(manifest_path)
373
+ dataset_id = (
374
+ payload.get("dataset_id")
375
+ if isinstance(payload, dict) and isinstance(payload.get("dataset_id"), str)
376
+ else manifest_path.stem
377
+ )
378
+ results.append(
379
+ generate_acquisition_manifest_file(
380
+ manifest_path,
381
+ destination / f"{dataset_id}.md",
382
+ )
383
+ )
384
+
385
+ failed = [result for result in results if not result.passed]
386
+ if failed:
387
+ return AcquisitionManifestBatchResult(
388
+ input_dir=source_dir,
389
+ output_dir=destination,
390
+ generated=tuple(results),
391
+ passed=False,
392
+ message="; ".join(result.message for result in failed),
393
+ )
394
+
395
+ destination.mkdir(parents=True, exist_ok=True)
396
+ _write_index(destination, results)
397
+ return AcquisitionManifestBatchResult(
398
+ input_dir=source_dir,
399
+ output_dir=destination,
400
+ generated=tuple(results),
401
+ passed=True,
402
+ message=f"Generated {len(results)} acquisition manifest(s).",
403
+ )
404
+
405
+
406
+ def _write_index(
407
+ output_dir: Path,
408
+ results: list[AcquisitionManifestGenerationResult],
409
+ ) -> None:
410
+ lines = [
411
+ "# Generated Acquisition Manifests",
412
+ "",
413
+ "These public-safe examples are generated from acquisition-manifest metadata.",
414
+ "",
415
+ "They record planning metadata only: no dataset downloaded, no acquisition executed, no redistribution rights confirmed, and no wet-lab validation by Permea.",
416
+ "",
417
+ ]
418
+ for result in results:
419
+ dataset_id = result.output_path.stem
420
+ lines.append(f"- [{dataset_id}]({dataset_id}.md)")
421
+ lines.append("")
422
+ output_dir.joinpath("README.md").write_text("\n".join(lines), encoding="utf-8")
423
+
424
+
425
+ def _entry_name(manifest: dict[str, Any]) -> str:
426
+ value = manifest.get("manifest_id")
427
+ if isinstance(value, str) and value:
428
+ return value
429
+ return "<acquisition_manifest>"
430
+
431
+
432
+ def _required_string(manifest: dict[str, Any], field: str) -> str:
433
+ value = manifest[field]
434
+ if not isinstance(value, str):
435
+ raise TypeError(f"{field} must be a string.")
436
+ return value
437
+
438
+
439
+ def _validate_enum(
440
+ *,
441
+ errors: list[AcquisitionManifestValidationError],
442
+ entry: str,
443
+ field: str,
444
+ value: Any,
445
+ allowed: frozenset[str],
446
+ ) -> None:
447
+ if value in allowed:
448
+ return
449
+ errors.append(
450
+ AcquisitionManifestValidationError(
451
+ entry=entry,
452
+ field=field,
453
+ message=f"{field} must be one of: " + ", ".join(sorted(allowed)),
454
+ )
455
+ )
456
+
457
+
458
+ def _render_list(value: Any) -> str:
459
+ if not isinstance(value, list) or not value:
460
+ return "- not specified"
461
+ return "\n".join(f"- {item}" for item in value)
462
+
463
+
464
+ def _format_validation_failure(
465
+ errors: tuple[AcquisitionManifestValidationError, ...],
466
+ ) -> str:
467
+ details = "; ".join(
468
+ f"{error.entry}.{error.field}: {error.message}" for error in errors
469
+ )
470
+ return f"Acquisition manifest validation failed: {details}"
@@ -0,0 +1,73 @@
1
+ """Benchmark definitions and registry surfaces for Permea Core."""
2
+
3
+ from .cards import (
4
+ DEFAULT_BENCHMARK_CARD_DIR,
5
+ BenchmarkCardBatchResult,
6
+ BenchmarkCardGenerationResult,
7
+ generate_benchmark_card_file,
8
+ generate_benchmark_cards_from_registry,
9
+ render_benchmark_card,
10
+ )
11
+ from .evidence_cards import (
12
+ DEFAULT_EVIDENCE_CARD_DIR,
13
+ DEFAULT_EVIDENCE_CARD_INPUTS,
14
+ EvidenceCardBatchResult,
15
+ EvidenceCardGenerationResult,
16
+ generate_evidence_card,
17
+ generate_evidence_cards_file,
18
+ generate_evidence_cards_for_inputs,
19
+ )
20
+ from .output_package import (
21
+ DEFAULT_OUTPUT_PACKAGE_DIR,
22
+ DEFAULT_OUTPUT_PACKAGE_INPUT,
23
+ OUTPUT_PACKAGE_FILES,
24
+ OutputPackageGenerationResult,
25
+ generate_evidence_cards,
26
+ generate_manifest,
27
+ generate_metrics,
28
+ generate_output_package,
29
+ generate_ranking,
30
+ )
31
+ from .registry import (
32
+ ALLOWED_MATURITY_LEVELS,
33
+ EXPECTED_OUTPUT_ARTIFACTS,
34
+ REQUIRED_REGISTRY_FIELDS,
35
+ BenchmarkDefinition,
36
+ BenchmarkRegistry,
37
+ RegistryValidationError,
38
+ RegistryValidationResult,
39
+ validate_registry_file,
40
+ )
41
+
42
+ __all__ = [
43
+ "ALLOWED_MATURITY_LEVELS",
44
+ "DEFAULT_BENCHMARK_CARD_DIR",
45
+ "DEFAULT_EVIDENCE_CARD_DIR",
46
+ "DEFAULT_EVIDENCE_CARD_INPUTS",
47
+ "DEFAULT_OUTPUT_PACKAGE_DIR",
48
+ "DEFAULT_OUTPUT_PACKAGE_INPUT",
49
+ "EXPECTED_OUTPUT_ARTIFACTS",
50
+ "OUTPUT_PACKAGE_FILES",
51
+ "BenchmarkCardBatchResult",
52
+ "EvidenceCardBatchResult",
53
+ "EvidenceCardGenerationResult",
54
+ "REQUIRED_REGISTRY_FIELDS",
55
+ "BenchmarkCardGenerationResult",
56
+ "BenchmarkDefinition",
57
+ "BenchmarkRegistry",
58
+ "OutputPackageGenerationResult",
59
+ "RegistryValidationError",
60
+ "RegistryValidationResult",
61
+ "generate_benchmark_card_file",
62
+ "generate_benchmark_cards_from_registry",
63
+ "generate_evidence_card",
64
+ "generate_evidence_cards",
65
+ "generate_evidence_cards_file",
66
+ "generate_evidence_cards_for_inputs",
67
+ "generate_manifest",
68
+ "generate_metrics",
69
+ "generate_output_package",
70
+ "generate_ranking",
71
+ "render_benchmark_card",
72
+ "validate_registry_file",
73
+ ]