benchcraft-core 0.1.0__tar.gz

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.
@@ -0,0 +1,25 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # OS
18
+ .DS_Store
19
+
20
+ # Editors
21
+ .vscode/
22
+ .idea/
23
+
24
+ # Local Claude settings
25
+ .claude/settings.local.json
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: benchcraft-core
3
+ Version: 0.1.0
4
+ Summary: Benchcraft Core: the thin, shared substrate used by all Benchcraft modules (data-tier conventions, OTel GenAI telemetry helpers, license-isolation policy).
5
+ Author: Benchcraft
6
+ License: MIT
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3 :: Only
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Requires-Python: >=3.11
11
+ Requires-Dist: opentelemetry-api>=1.20.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: pandas>=2.0; extra == 'dev'
14
+ Requires-Dist: polars>=0.20; extra == 'dev'
15
+ Requires-Dist: pyarrow>=14.0; extra == 'dev'
16
+ Requires-Dist: pytest>=7.0; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # lazycore
20
+
21
+ The thin, shared substrate underneath every Benchcraft module (AutoML,
22
+ LazyClean, LazyForecast, LazyGraph, LazyVision, LazyTune, LazyRed,
23
+ LazyAgent). It exists so that modules working on largely the same
24
+ underlying data, telemetry, and licensing concerns don't each invent their
25
+ own conventions -- without forcing premature unification of things that
26
+ genuinely differ per module.
27
+
28
+ ## This package is intentionally thin. Here's why.
29
+
30
+ Benchcraft's packaging model (architecture doc §2.7) is Hugging Face-style:
31
+ independently-versioned, separate packages per module, sharing one thin
32
+ `lazycore` package for common schemas/interfaces with near-zero
33
+ dependencies -- explicitly **not** one monorepo with pip extras. The reason
34
+ is concrete, not aesthetic: PyTorch-heavy modules (LazyTune, LazyVision,
35
+ LazyGraph), the deliberately PyTorch-free LazyClean (which stays under a
36
+ 100MB footprint by using ONNX Runtime instead of PyTorch), and the
37
+ Node-adjacent tooling implied by LazyRed's Promptfoo integration have
38
+ genuinely conflicting dependency universes that pip's extras resolver
39
+ cannot cleanly reconcile. If `lazycore` pulled in pandas, polars, or torch
40
+ as hard dependencies, every module -- including the ones explicitly
41
+ designed to avoid those dependencies -- would be forced to install them
42
+ just to get `import lazycore` to work. That defeats the entire point of
43
+ per-module packaging.
44
+
45
+ The architecture doc is equally explicit that formal, typed interface
46
+ contracts between modules (in the style of MLflow's model "flavors") are
47
+ **deferred** until at least two real modules actually need to exchange
48
+ data (§2.9) -- so `lazycore` does not attempt to be a data-contract system.
49
+ What it provides instead are lightweight, checked-in *conventions*:
50
+ type-hint-only interfaces, small helper functions, policy tables encoded as
51
+ data. Nothing here assumes what shape a future formal contract should take.
52
+
53
+ Concretely, `lazycore`'s runtime dependency footprint is exactly one
54
+ non-stdlib package: `opentelemetry-api` (never the SDK). It does not depend
55
+ on pandas, polars, torch, or any ML framework -- where those are referenced
56
+ for type hints, the imports are guarded behind `typing.TYPE_CHECKING` or
57
+ done lazily inside a function body, so importing `lazycore` never forces
58
+ any of them to be installed.
59
+
60
+ ## What's in here
61
+
62
+ Everything in this package maps directly to a locked decision in Part 2 of
63
+ `Benchcraft_Unified_Architecture.md`. Nothing module-specific belongs here
64
+ (see the repo's `CLAUDE.md`, "lazycore stays thin").
65
+
66
+ ### `lazycore.data` -- three-tier data/tensor conventions (§2.1)
67
+
68
+ - **Tier 1 (dense tabular/text/time-series):** small conversion/validation
69
+ helpers over Arrow-backed pandas 2.x (`ArrowDtype`) and Polars, since both
70
+ are confirmed near-zero-cost, interchangeable front-ends over the same
71
+ Arrow buffers. `is_arrow_backed_pandas`, `pandas_arrow_dtypes`,
72
+ `to_polars_zero_copy`, `from_polars_zero_copy`.
73
+ - **Tier 2 (sparse graph tensors):** `SparseGraphTensorAdapter`, an abstract
74
+ base class describing the COO/CSR-CSC conversion boundary DLPack cannot
75
+ represent. No graph-library dependency; LazyGraph provides concrete PyG-
76
+ and DGL-facing implementations.
77
+ - **Tier 3 (dense image/audio):** `DenseMediaPipeline`, an abstract base
78
+ class describing an FFCV-style decode → augment → DLPack-handoff
79
+ pipeline shape (decode/augment are compute-bound, not copy-bound, so
80
+ DLPack only applies at the final dense-tensor stage). LazyVision provides
81
+ concrete implementations.
82
+
83
+ ### `lazycore.telemetry` -- OpenTelemetry GenAI semantic conventions (§2.6)
84
+
85
+ Shared attribute-name constants (`security.severity`, `owasp.mapping`,
86
+ `ml.metric.*`) and a thin wrapper (`genai_span`, `set_security_finding`,
87
+ `set_ml_metric`, `add_transcript_event`) over `opentelemetry-api` so
88
+ LazyRed's security-audit reports, LazyAgent's execution trajectories, and
89
+ the ML leaderboards from AutoML/LazyForecast/LazyGraph/LazyVision all
90
+ report through the same schema. Depends only on `opentelemetry-api`; if the
91
+ calling application hasn't configured an SDK TracerProvider, spans are
92
+ OTel's documented no-ops -- safe to call, nothing exported until a real
93
+ exporter is wired up by whichever module needs one.
94
+
95
+ ### `lazycore.licensing` -- license-isolation and model-allowlist policy (§2.2, §2.10)
96
+
97
+ - `RiskType` / `Mitigation` / `RISK_MITIGATIONS`: the §2.2 License Isolation
98
+ Policy decision table, encoded as data rather than prose, so module
99
+ owners can look up the exact required mitigation for a given dependency
100
+ risk (GPL-at-build-time, restrictive optional build dep,
101
+ AGPL/GPL-at-runtime-internal, AGPL/GPL-network-facing,
102
+ source-available-non-compete, non-commercial weights).
103
+ - `ModelTier` / `ModelLicenseEntry` / `Allowlist`: the §2.10 mechanism every
104
+ module uses to register and check model checkpoints against Tier 1
105
+ (permissive, auto-usable) or Tier 2 (restricted, opt-in-gated) --
106
+ including the runtime guard that raises `RestrictedLicenseNotAcceptedError`
107
+ for a Tier 2 checkpoint unless the caller explicitly passes
108
+ `accept_restricted_licenses=True`.
109
+
110
+ This is a **policy and mechanism**, not a populated list. Every `Allowlist`
111
+ starts empty; populating and maintaining the actual per-module allowlists
112
+ (which specific model checkpoints go in Tier 1 vs Tier 2) is called out in
113
+ the architecture doc (Part 6) as an ongoing, per-module maintenance task,
114
+ not something `lazycore` does on a module's behalf.
115
+
116
+ ### `lazycore.sandbox` -- shared sandbox executor + adapter base class (§2.3, §2.3.1)
117
+
118
+ LazyRed and LazyAgent contain the same kernel-level threat class --
119
+ arbitrary code execution by a red-team target or a benchmarked agent -- so
120
+ per §2.3, LazyCore provides **one** shared sandbox executor and **one**
121
+ generic policy dataclass, with mode-specific policy *values* layered on
122
+ top by each module when it's built (LazyRed's "red-team target sandbox",
123
+ LazyAgent's "benchmark task sandbox"). Nothing module-specific (e.g. an
124
+ OWASP mapping, a benchmark-task allowlist) lives in this package -- only
125
+ the generic shape both modes share.
126
+
127
+ - `SandboxPolicy` -- generic, frozen dataclass config: `allow_network`,
128
+ `allowed_read_paths`, `allowed_write_paths`, `allowed_executables`,
129
+ plus env/timeout/cwd knobs. The exact same dataclass is meant to be
130
+ instantiated with different values for LazyRed vs. LazyAgent.
131
+ - `BaseSandboxExecutor` -- the shared ABC (`is_available`, `run_command`,
132
+ `run_callable`, returning a structured `SandboxResult`).
133
+ - `SeatbeltSandboxExecutor` -- the real, tested macOS backend. Generates an
134
+ SBPL (Sandbox Profile Language) profile from a `SandboxPolicy` and runs
135
+ the target command under `/usr/bin/sandbox-exec -f <profile> -- ...`.
136
+ - `LinuxNamespaceSandboxExecutor` -- a **documented stub**, not a real
137
+ implementation. It satisfies the same ABC and reports availability via
138
+ `shutil.which("bwrap"/"unshare")`, but every actual run method raises
139
+ `SandboxBackendUnavailableError`. This repository's reference/dev
140
+ environment is macOS, so a real gVisor/Firecracker/namespace-based
141
+ backend (the intended Linux implementation per §2.3, since Linux has no
142
+ VM-boundary GPU problem to design around) cannot be meaningfully built or
143
+ verified here. Do not treat this stub as production-ready.
144
+ - `get_default_executor()` -- returns `SeatbeltSandboxExecutor` on macOS
145
+ (when `/usr/bin/sandbox-exec` exists) or `LinuxNamespaceSandboxExecutor`
146
+ on Linux; raises `SandboxBackendUnavailableError` on anything else.
147
+
148
+ **Why GPU/Metal/MPS access is never sandboxed here, on either platform**
149
+ (§2.3.1): 2026 research confirmed no Mac container/VM runtime (Docker
150
+ Desktop, Podman+libkrun, Apple's `container`/Containerization framework)
151
+ exposes Metal/MPS passthrough into an isolation boundary, and -- more
152
+ fundamentally -- Seatbelt itself **cannot** gate GPU/Metal/Cocoa access
153
+ even in principle, because those are system-level services outside SBPL's
154
+ reach. The locked v1 design is a **split-trust architecture**: GPU-bound
155
+ model inference always runs unsandboxed (there's no adversarial surface in
156
+ local weights/forward-pass compute), and only the CPU-bound tool-calling/
157
+ code-execution layer -- shell commands, file I/O, network egress, the
158
+ actual adversarial surface in both LazyRed's and LazyAgent's threat models
159
+ -- is what this package ever constrains. `SeatbeltSandboxExecutor` does not
160
+ implement, and will never implement, any GPU-blocking rule; see its module
161
+ docstring for the exact technical reasoning.
162
+
163
+ Runtime dependencies added by this subpackage: **none** -- it uses only
164
+ `subprocess`, `shutil`, `tempfile`, `pickle`, `platform`, `dataclasses`,
165
+ and `abc` from the standard library.
166
+
167
+ ## What's deliberately NOT in here
168
+
169
+ - A *real* Linux sandbox backend -- `LinuxNamespaceSandboxExecutor` is a
170
+ documented stub only; see `lazycore.sandbox` above.
171
+ - Any LLM router or `BaseTarget`/multi-provider abstraction (§2.8) --
172
+ explicitly and permanently excluded platform-wide.
173
+ - Formal inter-module data contracts / MLflow "flavors"-style manifests
174
+ (§2.9) -- deferred until two real modules need to exchange data.
175
+ - pandas, polars, torch, or any ML framework as a hard dependency.
176
+
177
+ ## Installation
178
+
179
+ ```bash
180
+ cd packages/lazycore
181
+ pip install -e . # runtime only
182
+ pip install -e ".[dev]" # + pytest for running the test suite
183
+ ```
184
+
185
+ ## Running tests
186
+
187
+ ```bash
188
+ pytest packages/lazycore/tests
189
+ ```
190
+
191
+ The Tier 1 data-helper tests additionally require `pandas` and `polars` to
192
+ be installed in the test environment (they are not runtime dependencies of
193
+ `lazycore` itself, so those tests are skipped via `pytest.importorskip` if
194
+ unavailable).
195
+
196
+ `tests/sandbox/test_seatbelt.py` actually invokes `/usr/bin/sandbox-exec`
197
+ against real temp directories to demonstrate enforcement (an allowed write
198
+ succeeds, a write outside the policy is denied, network egress is denied
199
+ by default) -- it is skipped entirely on non-macOS hosts via
200
+ `pytest.mark.skipif`, rather than mocked. `tests/sandbox/test_linux_stub.py`
201
+ only verifies the documented-stub behavior of `LinuxNamespaceSandboxExecutor`
202
+ on this non-Linux machine (it raises `SandboxBackendUnavailableError`); it
203
+ cannot and does not validate real Linux namespace isolation.
@@ -0,0 +1,185 @@
1
+ # lazycore
2
+
3
+ The thin, shared substrate underneath every Benchcraft module (AutoML,
4
+ LazyClean, LazyForecast, LazyGraph, LazyVision, LazyTune, LazyRed,
5
+ LazyAgent). It exists so that modules working on largely the same
6
+ underlying data, telemetry, and licensing concerns don't each invent their
7
+ own conventions -- without forcing premature unification of things that
8
+ genuinely differ per module.
9
+
10
+ ## This package is intentionally thin. Here's why.
11
+
12
+ Benchcraft's packaging model (architecture doc §2.7) is Hugging Face-style:
13
+ independently-versioned, separate packages per module, sharing one thin
14
+ `lazycore` package for common schemas/interfaces with near-zero
15
+ dependencies -- explicitly **not** one monorepo with pip extras. The reason
16
+ is concrete, not aesthetic: PyTorch-heavy modules (LazyTune, LazyVision,
17
+ LazyGraph), the deliberately PyTorch-free LazyClean (which stays under a
18
+ 100MB footprint by using ONNX Runtime instead of PyTorch), and the
19
+ Node-adjacent tooling implied by LazyRed's Promptfoo integration have
20
+ genuinely conflicting dependency universes that pip's extras resolver
21
+ cannot cleanly reconcile. If `lazycore` pulled in pandas, polars, or torch
22
+ as hard dependencies, every module -- including the ones explicitly
23
+ designed to avoid those dependencies -- would be forced to install them
24
+ just to get `import lazycore` to work. That defeats the entire point of
25
+ per-module packaging.
26
+
27
+ The architecture doc is equally explicit that formal, typed interface
28
+ contracts between modules (in the style of MLflow's model "flavors") are
29
+ **deferred** until at least two real modules actually need to exchange
30
+ data (§2.9) -- so `lazycore` does not attempt to be a data-contract system.
31
+ What it provides instead are lightweight, checked-in *conventions*:
32
+ type-hint-only interfaces, small helper functions, policy tables encoded as
33
+ data. Nothing here assumes what shape a future formal contract should take.
34
+
35
+ Concretely, `lazycore`'s runtime dependency footprint is exactly one
36
+ non-stdlib package: `opentelemetry-api` (never the SDK). It does not depend
37
+ on pandas, polars, torch, or any ML framework -- where those are referenced
38
+ for type hints, the imports are guarded behind `typing.TYPE_CHECKING` or
39
+ done lazily inside a function body, so importing `lazycore` never forces
40
+ any of them to be installed.
41
+
42
+ ## What's in here
43
+
44
+ Everything in this package maps directly to a locked decision in Part 2 of
45
+ `Benchcraft_Unified_Architecture.md`. Nothing module-specific belongs here
46
+ (see the repo's `CLAUDE.md`, "lazycore stays thin").
47
+
48
+ ### `lazycore.data` -- three-tier data/tensor conventions (§2.1)
49
+
50
+ - **Tier 1 (dense tabular/text/time-series):** small conversion/validation
51
+ helpers over Arrow-backed pandas 2.x (`ArrowDtype`) and Polars, since both
52
+ are confirmed near-zero-cost, interchangeable front-ends over the same
53
+ Arrow buffers. `is_arrow_backed_pandas`, `pandas_arrow_dtypes`,
54
+ `to_polars_zero_copy`, `from_polars_zero_copy`.
55
+ - **Tier 2 (sparse graph tensors):** `SparseGraphTensorAdapter`, an abstract
56
+ base class describing the COO/CSR-CSC conversion boundary DLPack cannot
57
+ represent. No graph-library dependency; LazyGraph provides concrete PyG-
58
+ and DGL-facing implementations.
59
+ - **Tier 3 (dense image/audio):** `DenseMediaPipeline`, an abstract base
60
+ class describing an FFCV-style decode → augment → DLPack-handoff
61
+ pipeline shape (decode/augment are compute-bound, not copy-bound, so
62
+ DLPack only applies at the final dense-tensor stage). LazyVision provides
63
+ concrete implementations.
64
+
65
+ ### `lazycore.telemetry` -- OpenTelemetry GenAI semantic conventions (§2.6)
66
+
67
+ Shared attribute-name constants (`security.severity`, `owasp.mapping`,
68
+ `ml.metric.*`) and a thin wrapper (`genai_span`, `set_security_finding`,
69
+ `set_ml_metric`, `add_transcript_event`) over `opentelemetry-api` so
70
+ LazyRed's security-audit reports, LazyAgent's execution trajectories, and
71
+ the ML leaderboards from AutoML/LazyForecast/LazyGraph/LazyVision all
72
+ report through the same schema. Depends only on `opentelemetry-api`; if the
73
+ calling application hasn't configured an SDK TracerProvider, spans are
74
+ OTel's documented no-ops -- safe to call, nothing exported until a real
75
+ exporter is wired up by whichever module needs one.
76
+
77
+ ### `lazycore.licensing` -- license-isolation and model-allowlist policy (§2.2, §2.10)
78
+
79
+ - `RiskType` / `Mitigation` / `RISK_MITIGATIONS`: the §2.2 License Isolation
80
+ Policy decision table, encoded as data rather than prose, so module
81
+ owners can look up the exact required mitigation for a given dependency
82
+ risk (GPL-at-build-time, restrictive optional build dep,
83
+ AGPL/GPL-at-runtime-internal, AGPL/GPL-network-facing,
84
+ source-available-non-compete, non-commercial weights).
85
+ - `ModelTier` / `ModelLicenseEntry` / `Allowlist`: the §2.10 mechanism every
86
+ module uses to register and check model checkpoints against Tier 1
87
+ (permissive, auto-usable) or Tier 2 (restricted, opt-in-gated) --
88
+ including the runtime guard that raises `RestrictedLicenseNotAcceptedError`
89
+ for a Tier 2 checkpoint unless the caller explicitly passes
90
+ `accept_restricted_licenses=True`.
91
+
92
+ This is a **policy and mechanism**, not a populated list. Every `Allowlist`
93
+ starts empty; populating and maintaining the actual per-module allowlists
94
+ (which specific model checkpoints go in Tier 1 vs Tier 2) is called out in
95
+ the architecture doc (Part 6) as an ongoing, per-module maintenance task,
96
+ not something `lazycore` does on a module's behalf.
97
+
98
+ ### `lazycore.sandbox` -- shared sandbox executor + adapter base class (§2.3, §2.3.1)
99
+
100
+ LazyRed and LazyAgent contain the same kernel-level threat class --
101
+ arbitrary code execution by a red-team target or a benchmarked agent -- so
102
+ per §2.3, LazyCore provides **one** shared sandbox executor and **one**
103
+ generic policy dataclass, with mode-specific policy *values* layered on
104
+ top by each module when it's built (LazyRed's "red-team target sandbox",
105
+ LazyAgent's "benchmark task sandbox"). Nothing module-specific (e.g. an
106
+ OWASP mapping, a benchmark-task allowlist) lives in this package -- only
107
+ the generic shape both modes share.
108
+
109
+ - `SandboxPolicy` -- generic, frozen dataclass config: `allow_network`,
110
+ `allowed_read_paths`, `allowed_write_paths`, `allowed_executables`,
111
+ plus env/timeout/cwd knobs. The exact same dataclass is meant to be
112
+ instantiated with different values for LazyRed vs. LazyAgent.
113
+ - `BaseSandboxExecutor` -- the shared ABC (`is_available`, `run_command`,
114
+ `run_callable`, returning a structured `SandboxResult`).
115
+ - `SeatbeltSandboxExecutor` -- the real, tested macOS backend. Generates an
116
+ SBPL (Sandbox Profile Language) profile from a `SandboxPolicy` and runs
117
+ the target command under `/usr/bin/sandbox-exec -f <profile> -- ...`.
118
+ - `LinuxNamespaceSandboxExecutor` -- a **documented stub**, not a real
119
+ implementation. It satisfies the same ABC and reports availability via
120
+ `shutil.which("bwrap"/"unshare")`, but every actual run method raises
121
+ `SandboxBackendUnavailableError`. This repository's reference/dev
122
+ environment is macOS, so a real gVisor/Firecracker/namespace-based
123
+ backend (the intended Linux implementation per §2.3, since Linux has no
124
+ VM-boundary GPU problem to design around) cannot be meaningfully built or
125
+ verified here. Do not treat this stub as production-ready.
126
+ - `get_default_executor()` -- returns `SeatbeltSandboxExecutor` on macOS
127
+ (when `/usr/bin/sandbox-exec` exists) or `LinuxNamespaceSandboxExecutor`
128
+ on Linux; raises `SandboxBackendUnavailableError` on anything else.
129
+
130
+ **Why GPU/Metal/MPS access is never sandboxed here, on either platform**
131
+ (§2.3.1): 2026 research confirmed no Mac container/VM runtime (Docker
132
+ Desktop, Podman+libkrun, Apple's `container`/Containerization framework)
133
+ exposes Metal/MPS passthrough into an isolation boundary, and -- more
134
+ fundamentally -- Seatbelt itself **cannot** gate GPU/Metal/Cocoa access
135
+ even in principle, because those are system-level services outside SBPL's
136
+ reach. The locked v1 design is a **split-trust architecture**: GPU-bound
137
+ model inference always runs unsandboxed (there's no adversarial surface in
138
+ local weights/forward-pass compute), and only the CPU-bound tool-calling/
139
+ code-execution layer -- shell commands, file I/O, network egress, the
140
+ actual adversarial surface in both LazyRed's and LazyAgent's threat models
141
+ -- is what this package ever constrains. `SeatbeltSandboxExecutor` does not
142
+ implement, and will never implement, any GPU-blocking rule; see its module
143
+ docstring for the exact technical reasoning.
144
+
145
+ Runtime dependencies added by this subpackage: **none** -- it uses only
146
+ `subprocess`, `shutil`, `tempfile`, `pickle`, `platform`, `dataclasses`,
147
+ and `abc` from the standard library.
148
+
149
+ ## What's deliberately NOT in here
150
+
151
+ - A *real* Linux sandbox backend -- `LinuxNamespaceSandboxExecutor` is a
152
+ documented stub only; see `lazycore.sandbox` above.
153
+ - Any LLM router or `BaseTarget`/multi-provider abstraction (§2.8) --
154
+ explicitly and permanently excluded platform-wide.
155
+ - Formal inter-module data contracts / MLflow "flavors"-style manifests
156
+ (§2.9) -- deferred until two real modules need to exchange data.
157
+ - pandas, polars, torch, or any ML framework as a hard dependency.
158
+
159
+ ## Installation
160
+
161
+ ```bash
162
+ cd packages/lazycore
163
+ pip install -e . # runtime only
164
+ pip install -e ".[dev]" # + pytest for running the test suite
165
+ ```
166
+
167
+ ## Running tests
168
+
169
+ ```bash
170
+ pytest packages/lazycore/tests
171
+ ```
172
+
173
+ The Tier 1 data-helper tests additionally require `pandas` and `polars` to
174
+ be installed in the test environment (they are not runtime dependencies of
175
+ `lazycore` itself, so those tests are skipped via `pytest.importorskip` if
176
+ unavailable).
177
+
178
+ `tests/sandbox/test_seatbelt.py` actually invokes `/usr/bin/sandbox-exec`
179
+ against real temp directories to demonstrate enforcement (an allowed write
180
+ succeeds, a write outside the policy is denied, network egress is denied
181
+ by default) -- it is skipped entirely on non-macOS hosts via
182
+ `pytest.mark.skipif`, rather than mocked. `tests/sandbox/test_linux_stub.py`
183
+ only verifies the documented-stub behavior of `LinuxNamespaceSandboxExecutor`
184
+ on this non-Linux machine (it raises `SandboxBackendUnavailableError`); it
185
+ cannot and does not validate real Linux namespace isolation.
@@ -0,0 +1,43 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "benchcraft-core"
7
+ version = "0.1.0"
8
+ description = "Benchcraft Core: the thin, shared substrate used by all Benchcraft modules (data-tier conventions, OTel GenAI telemetry helpers, license-isolation policy)."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Benchcraft" }]
13
+ classifiers = [
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3.11",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ ]
18
+
19
+ dependencies = [
20
+ "opentelemetry-api>=1.20.0",
21
+ ]
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "pytest>=7.0",
26
+ # Test-only additions (CodeRabbit finding): lazycore.data's Tier-1
27
+ # helpers exercise pandas/polars, and pandas' pyarrow dtype backend
28
+ # additionally needs pyarrow installed. Without these in the `dev`
29
+ # extra, `pip install -e ".[dev]"` followed by `pytest` silently
30
+ # skips every Tier-1 test via `pytest.importorskip` in test_data.py --
31
+ # the documented test command never actually exercises that tier.
32
+ # lazycore's own runtime code (lazycore/data.py) still never hard-
33
+ # depends on any of these -- it imports them lazily, only when a
34
+ # caller actually invokes a Tier-1 helper -- so this does not weaken
35
+ # lazycore's "near-zero dependencies" runtime contract; it only adds
36
+ # to the test-time dependency set.
37
+ "pandas>=2.0",
38
+ "polars>=0.20",
39
+ "pyarrow>=14.0",
40
+ ]
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/lazycore"]
@@ -0,0 +1,100 @@
1
+ """lazycore: the thin, shared substrate underneath every Benchcraft module.
2
+
3
+ See the package README for scope and the "why thin" rationale. This module
4
+ re-exports the small public surface of ``lazycore.data``,
5
+ ``lazycore.telemetry``, ``lazycore.licensing``, and ``lazycore.sandbox`` so
6
+ most consumers only need ``import lazycore``.
7
+ """
8
+
9
+ from lazycore.data import (
10
+ ArrowBackedFrame,
11
+ DenseMediaPipeline,
12
+ SparseFormat,
13
+ SparseGraphTensorAdapter,
14
+ from_polars_zero_copy,
15
+ is_arrow_backed_pandas,
16
+ pandas_arrow_dtypes,
17
+ to_polars_zero_copy,
18
+ )
19
+ from lazycore.licensing import (
20
+ Allowlist,
21
+ Mitigation,
22
+ ModelLicenseEntry,
23
+ ModelTier,
24
+ RestrictedLicenseNotAcceptedError,
25
+ RISK_MITIGATIONS,
26
+ RiskType,
27
+ )
28
+ from lazycore.sandbox import (
29
+ BaseSandboxExecutor,
30
+ LinuxNamespaceSandboxExecutor,
31
+ SandboxBackendUnavailableError,
32
+ SandboxError,
33
+ SandboxPolicy,
34
+ SandboxPolicyViolationError,
35
+ SandboxResult,
36
+ SeatbeltSandboxExecutor,
37
+ get_default_executor,
38
+ )
39
+ from lazycore.telemetry import (
40
+ ATTR_GENAI_EVENT_CONTENT,
41
+ ATTR_GENAI_EVENT_ROLE,
42
+ ATTR_ML_METRIC_ACCURACY,
43
+ ATTR_ML_METRIC_PREFIX,
44
+ ATTR_OWASP_MAPPING,
45
+ ATTR_SECURITY_SEVERITY,
46
+ SecuritySeverity,
47
+ add_transcript_event,
48
+ genai_span,
49
+ get_tracer,
50
+ ml_metric_attribute,
51
+ set_ml_metric,
52
+ set_security_finding,
53
+ )
54
+
55
+ __version__ = "0.1.0"
56
+
57
+ __all__ = [
58
+ "__version__",
59
+ # data.py
60
+ "ArrowBackedFrame",
61
+ "DenseMediaPipeline",
62
+ "SparseFormat",
63
+ "SparseGraphTensorAdapter",
64
+ "from_polars_zero_copy",
65
+ "is_arrow_backed_pandas",
66
+ "pandas_arrow_dtypes",
67
+ "to_polars_zero_copy",
68
+ # licensing.py
69
+ "Allowlist",
70
+ "Mitigation",
71
+ "ModelLicenseEntry",
72
+ "ModelTier",
73
+ "RestrictedLicenseNotAcceptedError",
74
+ "RISK_MITIGATIONS",
75
+ "RiskType",
76
+ # sandbox/__init__.py
77
+ "BaseSandboxExecutor",
78
+ "LinuxNamespaceSandboxExecutor",
79
+ "SandboxBackendUnavailableError",
80
+ "SandboxError",
81
+ "SandboxPolicy",
82
+ "SandboxPolicyViolationError",
83
+ "SandboxResult",
84
+ "SeatbeltSandboxExecutor",
85
+ "get_default_executor",
86
+ # telemetry.py
87
+ "ATTR_GENAI_EVENT_CONTENT",
88
+ "ATTR_GENAI_EVENT_ROLE",
89
+ "ATTR_ML_METRIC_ACCURACY",
90
+ "ATTR_ML_METRIC_PREFIX",
91
+ "ATTR_OWASP_MAPPING",
92
+ "ATTR_SECURITY_SEVERITY",
93
+ "SecuritySeverity",
94
+ "add_transcript_event",
95
+ "genai_span",
96
+ "get_tracer",
97
+ "ml_metric_attribute",
98
+ "set_ml_metric",
99
+ "set_security_finding",
100
+ ]