ruthless-efficiency 0.2.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.
Files changed (109) hide show
  1. ruthless_efficiency-0.2.0/.gitattributes +10 -0
  2. ruthless_efficiency-0.2.0/.github/CODEOWNERS +1 -0
  3. ruthless_efficiency-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  4. ruthless_efficiency-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
  5. ruthless_efficiency-0.2.0/.github/dependabot.yml +13 -0
  6. ruthless_efficiency-0.2.0/.github/pull_request_template.md +19 -0
  7. ruthless_efficiency-0.2.0/.github/workflows/ci.yml +29 -0
  8. ruthless_efficiency-0.2.0/.github/workflows/publish.yml +35 -0
  9. ruthless_efficiency-0.2.0/.gitignore +11 -0
  10. ruthless_efficiency-0.2.0/.importlinter +44 -0
  11. ruthless_efficiency-0.2.0/CHANGELOG.md +58 -0
  12. ruthless_efficiency-0.2.0/CLAUDE.md +123 -0
  13. ruthless_efficiency-0.2.0/CODE_OF_CONDUCT.md +41 -0
  14. ruthless_efficiency-0.2.0/CONTRIBUTING.md +85 -0
  15. ruthless_efficiency-0.2.0/LICENSE +21 -0
  16. ruthless_efficiency-0.2.0/NOTICE +93 -0
  17. ruthless_efficiency-0.2.0/PKG-INFO +125 -0
  18. ruthless_efficiency-0.2.0/README.md +96 -0
  19. ruthless_efficiency-0.2.0/SECURITY.md +42 -0
  20. ruthless_efficiency-0.2.0/assets/ruthless-efficiency.jpg +0 -0
  21. ruthless_efficiency-0.2.0/benchmarks/test_perf_baselines.py +57 -0
  22. ruthless_efficiency-0.2.0/docs/adr/ADR-001-ast-sandbox-security-model.md +63 -0
  23. ruthless_efficiency-0.2.0/docs/audits/2026-05-28-audit-cleanup.md +102 -0
  24. ruthless_efficiency-0.2.0/docs/c4/architecture.dsl +176 -0
  25. ruthless_efficiency-0.2.0/docs/c4/architecture.html +432 -0
  26. ruthless_efficiency-0.2.0/docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase1a.md +1338 -0
  27. ruthless_efficiency-0.2.0/docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase1b.md +989 -0
  28. ruthless_efficiency-0.2.0/docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase2-library.md +633 -0
  29. ruthless_efficiency-0.2.0/docs/superpowers/specs/2026-05-28-optimization-engine-carveout-design.md +406 -0
  30. ruthless_efficiency-0.2.0/pyproject.toml +45 -0
  31. ruthless_efficiency-0.2.0/ruthless/__init__.py +74 -0
  32. ruthless_efficiency-0.2.0/ruthless/_io.py +37 -0
  33. ruthless_efficiency-0.2.0/ruthless/_logging.py +10 -0
  34. ruthless_efficiency-0.2.0/ruthless/backend.py +34 -0
  35. ruthless_efficiency-0.2.0/ruthless/backends/__init__.py +67 -0
  36. ruthless_efficiency-0.2.0/ruthless/backends/base.py +55 -0
  37. ruthless_efficiency-0.2.0/ruthless/backends/docker.py +20 -0
  38. ruthless_efficiency-0.2.0/ruthless/backends/hf_jobs.py +215 -0
  39. ruthless_efficiency-0.2.0/ruthless/backends/local_cuda.py +74 -0
  40. ruthless_efficiency-0.2.0/ruthless/backends/pool.py +91 -0
  41. ruthless_efficiency-0.2.0/ruthless/backends/remote_ssh.py +258 -0
  42. ruthless_efficiency-0.2.0/ruthless/backends/remote_worker.py +107 -0
  43. ruthless_efficiency-0.2.0/ruthless/cli.py +58 -0
  44. ruthless_efficiency-0.2.0/ruthless/config/__init__.py +55 -0
  45. ruthless_efficiency-0.2.0/ruthless/config/common.py +120 -0
  46. ruthless_efficiency-0.2.0/ruthless/config/space.py +51 -0
  47. ruthless_efficiency-0.2.0/ruthless/config/strategies.py +81 -0
  48. ruthless_efficiency-0.2.0/ruthless/errors.py +33 -0
  49. ruthless_efficiency-0.2.0/ruthless/guards.py +12 -0
  50. ruthless_efficiency-0.2.0/ruthless/objective.py +38 -0
  51. ruthless_efficiency-0.2.0/ruthless/parallel.py +42 -0
  52. ruthless_efficiency-0.2.0/ruthless/remote.py +64 -0
  53. ruthless_efficiency-0.2.0/ruthless/report.py +49 -0
  54. ruthless_efficiency-0.2.0/ruthless/result.py +52 -0
  55. ruthless_efficiency-0.2.0/ruthless/strategies/__init__.py +0 -0
  56. ruthless_efficiency-0.2.0/ruthless/strategies/evolve_/__init__.py +8 -0
  57. ruthless_efficiency-0.2.0/ruthless/strategies/evolve_/evaluator.py +163 -0
  58. ruthless_efficiency-0.2.0/ruthless/strategies/evolve_/sandbox.py +604 -0
  59. ruthless_efficiency-0.2.0/ruthless/strategies/evolve_/strategy.py +391 -0
  60. ruthless_efficiency-0.2.0/ruthless/strategies/optuna_/__init__.py +8 -0
  61. ruthless_efficiency-0.2.0/ruthless/strategies/optuna_/strategy.py +124 -0
  62. ruthless_efficiency-0.2.0/ruthless/strategies/random_/__init__.py +7 -0
  63. ruthless_efficiency-0.2.0/ruthless/strategies/random_/strategy.py +71 -0
  64. ruthless_efficiency-0.2.0/ruthless/strategy.py +22 -0
  65. ruthless_efficiency-0.2.0/ruthless/testing.py +44 -0
  66. ruthless_efficiency-0.2.0/ruthless/wire.py +39 -0
  67. ruthless_efficiency-0.2.0/tests/backends/__init__.py +0 -0
  68. ruthless_efficiency-0.2.0/tests/backends/test_backend_timeout_retry.py +52 -0
  69. ruthless_efficiency-0.2.0/tests/backends/test_base.py +61 -0
  70. ruthless_efficiency-0.2.0/tests/backends/test_create_backend.py +27 -0
  71. ruthless_efficiency-0.2.0/tests/backends/test_docker.py +19 -0
  72. ruthless_efficiency-0.2.0/tests/backends/test_hf_jobs.py +133 -0
  73. ruthless_efficiency-0.2.0/tests/backends/test_local_cuda.py +92 -0
  74. ruthless_efficiency-0.2.0/tests/backends/test_pool.py +93 -0
  75. ruthless_efficiency-0.2.0/tests/backends/test_remote_ssh.py +163 -0
  76. ruthless_efficiency-0.2.0/tests/backends/test_remote_worker.py +58 -0
  77. ruthless_efficiency-0.2.0/tests/e2e/__init__.py +0 -0
  78. ruthless_efficiency-0.2.0/tests/e2e/test_determinism_convergence_gate.py +51 -0
  79. ruthless_efficiency-0.2.0/tests/e2e/test_evolve_orchestration_gate.py +116 -0
  80. ruthless_efficiency-0.2.0/tests/e2e/test_optuna_resume_gate.py +45 -0
  81. ruthless_efficiency-0.2.0/tests/fixtures/__init__.py +0 -0
  82. ruthless_efficiency-0.2.0/tests/fixtures/objectives.py +9 -0
  83. ruthless_efficiency-0.2.0/tests/strategies/evolve/__init__.py +0 -0
  84. ruthless_efficiency-0.2.0/tests/strategies/evolve/test_evolve_evaluator.py +124 -0
  85. ruthless_efficiency-0.2.0/tests/strategies/evolve/test_evolve_strategy.py +149 -0
  86. ruthless_efficiency-0.2.0/tests/strategies/evolve/test_sandbox.py +359 -0
  87. ruthless_efficiency-0.2.0/tests/strategies/optuna_/__init__.py +0 -0
  88. ruthless_efficiency-0.2.0/tests/strategies/optuna_/test_cached_objective.py +24 -0
  89. ruthless_efficiency-0.2.0/tests/strategies/optuna_/test_optuna_cached.py +50 -0
  90. ruthless_efficiency-0.2.0/tests/strategies/optuna_/test_optuna_strategy.py +55 -0
  91. ruthless_efficiency-0.2.0/tests/test_assert_cache_equivalence.py +78 -0
  92. ruthless_efficiency-0.2.0/tests/test_backend.py +22 -0
  93. ruthless_efficiency-0.2.0/tests/test_candidate_program.py +15 -0
  94. ruthless_efficiency-0.2.0/tests/test_cli.py +13 -0
  95. ruthless_efficiency-0.2.0/tests/test_config.py +66 -0
  96. ruthless_efficiency-0.2.0/tests/test_errors.py +26 -0
  97. ruthless_efficiency-0.2.0/tests/test_evolve_config.py +76 -0
  98. ruthless_efficiency-0.2.0/tests/test_guards.py +13 -0
  99. ruthless_efficiency-0.2.0/tests/test_logging.py +16 -0
  100. ruthless_efficiency-0.2.0/tests/test_objective.py +13 -0
  101. ruthless_efficiency-0.2.0/tests/test_optuna_config.py +47 -0
  102. ruthless_efficiency-0.2.0/tests/test_parallel.py +13 -0
  103. ruthless_efficiency-0.2.0/tests/test_public_api.py +74 -0
  104. ruthless_efficiency-0.2.0/tests/test_random_strategy.py +70 -0
  105. ruthless_efficiency-0.2.0/tests/test_remote.py +35 -0
  106. ruthless_efficiency-0.2.0/tests/test_report.py +24 -0
  107. ruthless_efficiency-0.2.0/tests/test_result.py +34 -0
  108. ruthless_efficiency-0.2.0/tests/test_strategy_port.py +17 -0
  109. ruthless_efficiency-0.2.0/uv.lock +1669 -0
@@ -0,0 +1,10 @@
1
+ # Normalize line endings to LF in the repository for cross-platform consistency
2
+ # (CI runs on Linux; contributors may be on Windows/macOS).
3
+ * text=auto eol=lf
4
+
5
+ # Binary assets — never normalize.
6
+ *.png binary
7
+ *.jpg binary
8
+ *.jpeg binary
9
+ *.gif binary
10
+ *.ico binary
@@ -0,0 +1 @@
1
+ * @karsten-s-nielsen
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: Bug Report
3
+ about: Report a bug in ruthless-efficiency
4
+ title: "[Bug] "
5
+ labels: bug
6
+ ---
7
+
8
+ **Describe the bug**
9
+ A clear description of what the bug is.
10
+
11
+ **To reproduce**
12
+ ```python
13
+ # Minimal code to reproduce
14
+ ```
15
+
16
+ **Expected behavior**
17
+ What you expected to happen.
18
+
19
+ **Environment**
20
+ - ruthless-efficiency version:
21
+ - Python version:
22
+ - numpy version:
23
+ - pydantic version:
24
+ - OS:
25
+
26
+ **Additional context**
27
+ Any other context (stack trace, config sample, etc.)
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest a feature for ruthless-efficiency
4
+ title: "[Feature] "
5
+ labels: enhancement
6
+ ---
7
+
8
+ **Is this related to a problem?**
9
+ A clear description of the problem. E.g., "I'm frustrated when..."
10
+
11
+ **Proposed solution**
12
+ Describe the solution you'd like.
13
+
14
+ **Alternatives considered**
15
+ Any alternative solutions or features you've considered.
16
+
17
+ **Additional context**
18
+ Any other context (links to papers, related strategies/backends, etc.)
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 5
8
+
9
+ - package-ecosystem: "github-actions"
10
+ directory: "/"
11
+ schedule:
12
+ interval: "weekly"
13
+ open-pull-requests-limit: 5
@@ -0,0 +1,19 @@
1
+ ## Summary
2
+
3
+ Brief description of what this PR does.
4
+
5
+ ## Changes
6
+
7
+ -
8
+
9
+ ## Testing
10
+
11
+ - [ ] Tests pass (`pytest -v`)
12
+ - [ ] Lint clean (`ruff check ruthless tests`)
13
+ - [ ] Format clean (`ruff format --check ruthless tests`)
14
+ - [ ] Types clean (`pyright`)
15
+ - [ ] Import contracts kept (`lint-imports`)
16
+
17
+ ## Related issues
18
+
19
+ Closes #
@@ -0,0 +1,29 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
8
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
9
+ - run: uv python install 3.10
10
+ - run: uv venv --python 3.10
11
+ - run: uv pip install -e ".[dev,backends,evolve,optuna]"
12
+ - run: uv run ruff check ruthless tests
13
+ - run: uv run ruff format --check ruthless tests
14
+ - run: uv run pyright
15
+ - run: uv run lint-imports
16
+ - run: uv run pytest -v
17
+
18
+ core-lean:
19
+ # Proves the default install stays dependency-light: core imports + the core test subset
20
+ # must pass WITHOUT the [backends]/[evolve]/[optuna] heavy deps (huggingface_hub/docker/openevolve/optuna).
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
24
+ - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
25
+ - run: uv python install 3.10
26
+ - run: uv venv --python 3.10
27
+ - run: uv pip install -e ".[dev]"
28
+ - run: uv run python -c "import ruthless; from ruthless.strategies.random_.strategy import RandomSearchStrategy; print(ruthless.__version__)"
29
+ - run: uv run pytest -v --ignore=tests/backends --ignore=tests/strategies/evolve --ignore=tests/e2e/test_evolve_orchestration_gate.py --ignore=tests/strategies/optuna_ --ignore=tests/e2e/test_optuna_resume_gate.py
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
12
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
13
+ with:
14
+ python-version: "3.12"
15
+ - run: pip install build
16
+ - run: python -m build
17
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
18
+ with:
19
+ name: dist
20
+ path: dist/
21
+
22
+ publish:
23
+ needs: build
24
+ runs-on: ubuntu-latest
25
+ environment: pypi
26
+ permissions:
27
+ id-token: write
28
+ steps:
29
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
30
+ with:
31
+ name: dist
32
+ path: dist/
33
+ - uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
34
+ with:
35
+ print-hash: true
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .ruff_cache/
5
+ .pytest_cache/
6
+ dist/
7
+ *.egg-info/
8
+ .import_linter_cache/
9
+
10
+ # Claude Code
11
+ .claude/
@@ -0,0 +1,44 @@
1
+ [importlinter]
2
+ root_packages =
3
+ ruthless
4
+
5
+ [importlinter:contract:core-isolation]
6
+ name = core must not import strategies or backends
7
+ type = forbidden
8
+ source_modules =
9
+ ruthless._io
10
+ ruthless._logging
11
+ ruthless.errors
12
+ ruthless.result
13
+ ruthless.objective
14
+ ruthless.backend
15
+ ruthless.strategy
16
+ ruthless.guards
17
+ ruthless.parallel
18
+ ruthless.config
19
+ ruthless.config.common
20
+ ruthless.config.space
21
+ ruthless.config.strategies
22
+ ruthless.report
23
+ ruthless.remote
24
+ ruthless.testing
25
+ ruthless.wire
26
+ forbidden_modules =
27
+ ruthless.strategies
28
+ ruthless.backends
29
+
30
+ [importlinter:contract:strategy-isolation]
31
+ name = strategies must not import backends or each other
32
+ type = forbidden
33
+ source_modules =
34
+ ruthless.strategies
35
+ forbidden_modules =
36
+ ruthless.backends
37
+
38
+ [importlinter:contract:backends-isolation]
39
+ name = backends must not import strategies
40
+ type = forbidden
41
+ source_modules =
42
+ ruthless.backends
43
+ forbidden_modules =
44
+ ruthless.strategies
@@ -0,0 +1,58 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (with the usual `0.x` caveat: the public
6
+ API may change between minor versions until `1.0`).
7
+
8
+ ## [0.2.0] - 2026-05-28
9
+
10
+ First published release. Ships the Phase 2 `[optuna]` extra alongside the Phase 1A/1B core, and folds
11
+ in the 2026-05-28 audit cleanup (curated public API, value-object immutability, security hardening).
12
+
13
+ ### Added
14
+ - `[optuna]` extra: `OptunaStrategy` — resumable Bayesian/sampler calibration on a SQLite study
15
+ (single-process resume; warm-start; C3 resume contract).
16
+ - `CachedObjective` core Protocol (one-time `prepare()` invariant + per-trial `evaluate_patch`) and
17
+ `ruthless.testing.assert_cache_equivalence`, proving the fast path equals the full recompute.
18
+ - Curated top-level public API: import the supported surface from `ruthless` directly
19
+ (`from ruthless import Candidate, RandomConfig, RandomSearchStrategy, InProcessBackend, ...`), with
20
+ an explicit `__all__`. Per-strategy namespaces re-export their strategy
21
+ (`ruthless.strategies.random_`, `…optuna_`, `…evolve_`).
22
+ - `ruthless.wire` — single source of truth for the cross-wire failure/score contract
23
+ (`combined_score` / `error` / `_error_text`), replacing magic strings duplicated across backends.
24
+ - `docs/adr/ADR-001-ast-sandbox-security-model.md` — the security model behind the evolve AST
25
+ allowlist (previously a dangling reference).
26
+ - `benchmarks/` — pytest-benchmark performance baselines for the random-search loop and
27
+ `assert_cache_equivalence` (not part of the default test run).
28
+
29
+ ### Changed
30
+ - `ruthless.config` is now a package (`space` / `common` / `strategies` submodules) instead of a
31
+ single module. All public names still import from `ruthless.config` — no import sites change.
32
+ - `Candidate.params` is now a read-only mapping (frozen + defensively copied at construction) and
33
+ `Choice.choices` is a tuple, enforcing the value-object immutability the dedup-key invariant relies
34
+ on. Consumers that need a mutable copy use `dict(candidate.params)`.
35
+
36
+ ### Security
37
+ - SSH backend: all `ssh`/`scp` calls now use `BatchMode=yes` and `StrictHostKeyChecking=accept-new`;
38
+ `HF_TOKEN` is transferred to the remote node via a 0600 file (read once, then unlinked) instead of
39
+ an inline command-line env prefix, keeping it out of the remote `ps`/shell history.
40
+ - `BackendConfig` validates `device` / `ssh_remote_dir` / `ssh_python_path` against a shell-safe
41
+ allowlist (blocks injection when a config is sourced from templated input).
42
+ - CI workflow actions are pinned to commit SHAs (supply-chain hardening), matching the publish
43
+ workflow.
44
+
45
+ ## [0.1.0]
46
+
47
+ ### Added
48
+ - Hexagonal core: the `Objective`, `SearchStrategy`, and `ComputeBackend` ports; the `Candidate`,
49
+ `Metrics`, `Evaluation`, and `Result` value types; the discriminated-union config surface; JSON +
50
+ Markdown reporting; the unified error taxonomy (`TransientEvaluationError` /
51
+ `FatalEvaluationError`); and `InProcessBackend`.
52
+ - `RandomSearchStrategy` — the built-in zero-dependency baseline and the driver of the
53
+ determinism/convergence gate (Phase 1A).
54
+ - `[backends]` extra: `BackendPool` (priority-ordered dispatch + bounded transient-retry) over
55
+ `local_cuda` / `remote_ssh` / `hf_jobs` / `docker`, with the `RemoteObjective` / `RemoteRef`
56
+ remote-resolution contract (Phase 1B).
57
+ - `[evolve]` extra: `EvolveStrategy` — a thin orchestration adapter over OpenEvolve — plus the AST
58
+ allowlist validator for Level-2 code evolution (Phase 1B).
@@ -0,0 +1,123 @@
1
+ # ruthless-efficiency
2
+
3
+ A general optimisation/search substrate: a pure hexagonal core + pluggable search strategies +
4
+ pluggable compute backends. Ships at `0.2.0` (`0.x` — API unstable). **Phase 1A** delivered the core
5
+ ports + built-in `RandomSearchStrategy` (determinism gate). **Phase 1B (library side)** adds the
6
+ optional `[backends]` extra (`BackendPool` + `local_cuda`/`remote_ssh`/`hf_jobs`/`docker`, with the
7
+ per-candidate timeout + transient-retry contract) and the `[evolve]` extra (`EvolveStrategy`, a thin
8
+ adapter over OpenEvolve, + the AST sandbox). **Phase 2 (library side)** adds the `[optuna]` extra
9
+ (`OptunaStrategy` — resumable Bayesian/sampler calibration; `CachedObjective` invariant-prep /
10
+ per-trial-patch port + `ruthless.testing.assert_cache_equivalence`). The consumer migrations (lakehouse
11
+ evolve, and **silly-kicks adopting `ruthless[optuna]`** for its own calibrations) run in those repos,
12
+ not here.
13
+
14
+ ## Architecture
15
+
16
+ - **Hexagonal.** `ruthless/` is the pure core: it defines the **ports** (`Objective`,
17
+ `SearchStrategy`, `ComputeBackend` — structural `Protocol`s) and **value types** (`Candidate`,
18
+ `Metrics = dict[str, float]`, `Evaluation`, `Result`). The core depends only on `pydantic` +
19
+ `numpy` (+ `pyyaml`).
20
+ - **One-way dependency direction.** Strategies (`ruthless/strategies/`) and backends
21
+ (`ruthless/backends/`) depend on the core, never the reverse; strategies do not import each other or
22
+ the backends package, and backends do not import strategies. Enforced by import-linter
23
+ (`.importlinter`, **3 contracts**) — `lint-imports` must stay green. (`EvolveStrategy` receives a
24
+ backend via `run(objective, *, backend)`; its OpenEvolve worker script imports `create_backend` at
25
+ runtime in the worker subprocess — not a static strategy→backends import.)
26
+ - **Each strategy owns its loop.** The core imposes no template-method driver. A strategy drives the
27
+ search and returns a `Result`; `report.py` renders it (JSON + Markdown). Persistence/resume is
28
+ strategy-internal.
29
+ - **Backends are the inter-candidate dispatch path.** One evaluation → one compute resource, on the
30
+ single port `evaluate(candidate, objective, *, timeout) -> Metrics`. `InProcessBackend` (core) runs
31
+ `objective.evaluate(candidate)` for pure/CPU objectives. The `[backends]` compute backends require a
32
+ **`RemoteObjective`** (an objective that opts into remote execution via a `RemoteRef` = install spec
33
+ + `module:callable` entrypoint, replacing the old `shared.wheel`/`target` convention); they resolve
34
+ and run the entrypoint (`local_cuda` in-process; `remote_ssh`/`hf_jobs` on a node). The
35
+ cross-process backends (`remote_ssh`/`hf_jobs`) enforce the per-candidate `timeout`; the in-process
36
+ ones (`InProcessBackend`, `local_cuda`) accept it for port compatibility but cannot cancel
37
+ in-process work, so they document-and-ignore it. `BackendPool` is a priority-ordered pool with a
38
+ bounded transient-retry contract.
39
+ - **Unified error model (1B).** Backends never record a sentinel score: they **raise**
40
+ `TransientEvaluationError` (transport/infra — retried by the pool) or `FatalEvaluationError`
41
+ (unparseable output / missing `remote_ref` / a node-side objective-crash marker). For evolve, the
42
+ `EvolveEvaluator` is the **single** place that maps any failure to the OpenEvolve worst-score
43
+ sentinel (objective vs. infra distinguished in artifacts), because OpenEvolve needs a score per
44
+ candidate.
45
+
46
+ ## Key conventions
47
+
48
+ - **Scored-metric finiteness only.** `classify_metric()` raises `FatalEvaluationError` if the
49
+ *optimisation-target* metric is inf/NaN. Diagnostic/auxiliary metrics are allowed to be non-finite
50
+ — never pass them to `classify_metric()`.
51
+ - **Fatal errors vs. penalties are distinct.** Fatal evaluation failures (`ruthless.errors`) are
52
+ surfaced and **never** recorded as a score. Degenerate-but-valid candidates get a recorded penalty
53
+ (`ruthless.guards.penalty_metrics`) — a finite, deliberately-bad score, not an error.
54
+ - **`Candidate` is hashable** (frozen, order-independent `__eq__`/`__hash__` over its params) so it
55
+ can serve as a cache/dedup key. Do not mutate `params` after construction.
56
+ - **`Result` is treat-as-immutable once returned** by `SearchStrategy.run`.
57
+ - **Config is a discriminated-union surface.** `RuthlessConfig` carries a discriminated *strategy*
58
+ union and a discriminated *param-space* union (`FloatRange` / `IntRange` / `Choice`, with a `log`
59
+ flag on floats). Only `random` is registered in Phase 1A; evolve/optuna extend the union later
60
+ without a breaking change.
61
+ - **Library never configures root logging.** Use `ruthless._logging.get_logger(name)` →
62
+ `logging.getLogger("ruthless.<name>")`. No handlers are attached; consumers own that.
63
+ - **The CLI objective loader is trusted-config-only.** `resolve_objective("pkg.mod:attr")` uses
64
+ `importlib` + `getattr` (never `eval`) and isinstance-checks against `Objective` (a name-only
65
+ guard). Programmatic construction is the primary API.
66
+
67
+ ## Local quality gate (mirrors CI exactly)
68
+
69
+ Run all five before declaring work done (Shift Left — catch it locally, not in CI):
70
+
71
+ ```bash
72
+ uv run ruff check ruthless tests
73
+ uv run ruff format --check ruthless tests
74
+ uv run pyright
75
+ uv run lint-imports
76
+ uv run pytest -v
77
+ ```
78
+
79
+ `pyright` runs on **both** `ruthless` and `tests` (see `[tool.pyright] include`).
80
+
81
+ ## Workflow conventions
82
+
83
+ - **TDD** — write the failing test first, then implement (red → green per change).
84
+ - **`/final-review`** is the mandatory pre-commit quality gate for every work cycle (it also
85
+ generates/updates the C4 diagram at `docs/c4/architecture.html`).
86
+ - **No commit without explicit user approval.**
87
+ - **No git worktrees** — project convention; work on a feature branch in this repo.
88
+
89
+ ## Tech stack
90
+
91
+ Python ≥3.10 (CI on 3.10), pydantic v2, numpy (`<3`, pinned for RNG-stream stability of the
92
+ determinism gate), pyyaml. Dev: pytest + hypothesis, ruff, pyright, import-linter, hatchling.
93
+
94
+ ## Scope map
95
+
96
+ - **Phase 1A (done):** core ports + value types + config + reporting + observability +
97
+ `RandomSearchStrategy` + the determinism/convergence gate.
98
+ - **Plan 1B — library side (done):** `[backends]` (`BackendPool` + `local_cuda`/`remote_ssh`/`hf_jobs`/
99
+ `docker`, timeout + transient-retry contract, `RemoteObjective`/`RemoteRef`) and `[evolve]`
100
+ (`EvolveStrategy` over OpenEvolve + the AST sandbox). **Part C (lakehouse consumer migration)** is
101
+ pending and runs in the lakehouse repo (behind its hard-gate).
102
+ - **Phase 2 — library side (done):** `[optuna]` (`OptunaStrategy` — resumable SQLite study, warm-start,
103
+ C3 resume contract; `CachedObjective` + `ruthless.testing.assert_cache_equivalence`). Group-scoring
104
+ was **deferred** (consumer runs CV in its own `score_fn`). **Consumer adoption pending:** silly-kicks
105
+ installs `ruthless[optuna]` and owns its parameter objectives (the first real consumer); lakehouse
106
+ evolve + TC3 migrations later.
107
+
108
+ ## Key Phase-2 conventions
109
+
110
+ - **`CachedObjective`** (core Protocol, no optuna dep): full `evaluate` + `prepare()` (invariant, once)
111
+ + `evaluate_patch(invariant, candidate)` + `patch_params`. `OptunaStrategy` uses the fast path and
112
+ rejects tuning any param not in `patch_params` (H1/M5). `assert_cache_equivalence` proves fast==full
113
+ and ENFORCES that candidates vary every patch_param.
114
+ - **OptunaStrategy resume (C3):** no lost/dup trials + monotone growth + converge — NOT trajectory
115
+ identity (Optuna doesn't persist sampler RNG). `best`/`history` are reconstructed from `study.trials`
116
+ so they span the whole store on resume. SQLite store = single-process only.
117
+
118
+ ## Reference docs
119
+
120
+ - Spec: `docs/superpowers/specs/2026-05-28-optimization-engine-carveout-design.md`
121
+ - Phase 1A plan: `docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase1a.md`
122
+ - Phase 1B plan (rev 3): `docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase1b.md`
123
+ - Phase 2 plan (rev 3): `docs/superpowers/plans/2026-05-28-ruthless-efficiency-phase2-library.md`
@@ -0,0 +1,41 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Using welcoming and inclusive language
17
+ - Being respectful of differing viewpoints and experiences
18
+ - Gracefully accepting constructive criticism
19
+ - Focusing on what is best for the community
20
+ - Showing empathy towards other community members
21
+
22
+ Examples of unacceptable behavior:
23
+
24
+ - The use of sexualized language or imagery, and sexual attention or advances
25
+ - Trolling, insulting or derogatory comments, and personal or political attacks
26
+ - Public or private harassment
27
+ - Publishing others' private information without explicit permission
28
+ - Other conduct which could reasonably be considered inappropriate
29
+
30
+ ## Enforcement
31
+
32
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
33
+ reported to the project maintainers. All complaints will be reviewed and
34
+ investigated and will result in a response that is deemed necessary and
35
+ appropriate to the circumstances.
36
+
37
+ ## Attribution
38
+
39
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
40
+ version 2.1, available at
41
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
@@ -0,0 +1,85 @@
1
+ # Contributing to ruthless-efficiency
2
+
3
+ ## Development Setup
4
+
5
+ ```bash
6
+ git clone https://github.com/karsten-s-nielsen/ruthless-efficiency.git
7
+ cd ruthless-efficiency
8
+ uv venv --python 3.10
9
+ uv pip install -e ".[dev]" # core-only dev install
10
+ # For the FULL test suite (backends/evolve/optuna tests + e2e gates), install the extras too:
11
+ uv pip install -e ".[dev,backends,evolve,optuna]"
12
+ ```
13
+
14
+ The core-only install (`.[dev]`) runs the core test subset; the backend/strategy tests under
15
+ `tests/backends/`, `tests/strategies/evolve/`, and `tests/strategies/optuna_/` (and their e2e gates)
16
+ require the extras. CI runs both: a full `test` job with all extras and a `core-lean` job that proves
17
+ the default install stays dependency-light.
18
+
19
+ ## Running Tests
20
+
21
+ ```bash
22
+ # Full suite
23
+ uv run pytest -v
24
+
25
+ # A single module
26
+ uv run pytest tests/test_random_strategy.py -v
27
+
28
+ # Performance baselines (not part of the default run — see benchmarks/)
29
+ uv run pytest benchmarks/ --benchmark-only
30
+ ```
31
+
32
+ ## Code Quality
33
+
34
+ The full local gate mirrors CI exactly:
35
+
36
+ ```bash
37
+ uv run ruff check ruthless tests
38
+ uv run ruff format --check ruthless tests
39
+ uv run pyright
40
+ uv run lint-imports
41
+ uv run pytest -v
42
+ ```
43
+
44
+ All five must pass before opening a PR (Shift Left — catch it locally, not in CI).
45
+
46
+ ## Pull Request Process
47
+
48
+ 1. Create a feature branch from `main`
49
+ 2. Write tests first (TDD preferred — red → green per change)
50
+ 3. Ensure the full gate above is green
51
+ 4. Keep commits focused — one logical change per commit
52
+ 5. Include a clear description of what and why
53
+
54
+ ## Architecture Guidelines
55
+
56
+ - **Hexagonal / pure core.** `ruthless/` defines the ports (`Objective`, `SearchStrategy`,
57
+ `ComputeBackend`) and value types (`Candidate`, `Metrics`, `Result`) and depends only on
58
+ `pydantic` + `numpy` (+ `pyyaml`).
59
+ - **Dependency direction is one-way.** Strategies and backends depend on the core, never the reverse.
60
+ This is enforced by import-linter (`.importlinter`) — `lint-imports` must stay green.
61
+ - **Each strategy owns its loop.** The core imposes no template-method driver; a strategy drives the
62
+ search and returns a `Result` that `report.py` renders.
63
+ - **Error taxonomy vs. penalties.** Fatal evaluation failures (`ruthless.errors`) are surfaced and
64
+ never recorded as a score; degenerate-but-valid candidates get a recorded penalty
65
+ (`ruthless.guards`). Only the *scored* metric is checked for finiteness. The cross-wire
66
+ failure-marker vocabulary (`combined_score`/`error`/`_error_text`) lives in `ruthless.wire`.
67
+ - **Remote execution (`[backends]`).** Compute backends require a `RemoteObjective` exposing a
68
+ `RemoteRef` (install spec + `module:callable` entrypoint); `BackendPool` adds priority-ordered
69
+ dispatch with a bounded transient-retry contract. Backends *raise* `TransientEvaluationError`
70
+ (retried) or `FatalEvaluationError` (surfaced) — they never record a sentinel.
71
+ - **Cached objectives (`[optuna]`).** `CachedObjective` (a core Protocol) declares a one-time
72
+ `prepare()` invariant + a per-trial `evaluate_patch`; `ruthless.testing.assert_cache_equivalence`
73
+ proves the fast path equals the full recompute. `OptunaStrategy` uses the fast path.
74
+ - New public functions and classes need docstrings explaining what they do and how to use them.
75
+
76
+ For the system-level view, download [`docs/c4/architecture.html`](docs/c4/architecture.html) and open
77
+ it in a browser (C4 System Context / Container / Component diagrams). The conventions above are
78
+ detailed in [`CLAUDE.md`](CLAUDE.md); the design rationale is in the
79
+ [spec](docs/superpowers/specs/2026-05-28-optimization-engine-carveout-design.md).
80
+
81
+ ## Versioning
82
+
83
+ The project is `0.x` — the ports are still being validated against real consumers. Breaking changes
84
+ to the public ports (`Objective`, `SearchStrategy`, `ComputeBackend`) and value types may occur before
85
+ `1.0`. Every release — and any breaking change — is recorded in [CHANGELOG.md](CHANGELOG.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karsten S. Nielsen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,93 @@
1
+ ruthless-efficiency
2
+ Copyright (c) 2026 Karsten S. Nielsen
3
+
4
+ This product is original work, released under the MIT License (see LICENSE).
5
+ It is not a fork. The name and tagline are a homage to Monty Python (see
6
+ "Assets and Cultural Attribution" below).
7
+
8
+
9
+ Third-Party Libraries (runtime)
10
+ -------------------------------
11
+
12
+ Installed with the default distribution. Each retains its own upstream license;
13
+ the SPDX expressions below were verified against the installed package metadata.
14
+
15
+ pydantic --- data validation / settings (MIT License).
16
+ See: https://github.com/pydantic/pydantic
17
+
18
+ numpy --- numerical arrays and the seeded RNG used by RandomSearchStrategy
19
+ (BSD-3-Clause License). Copyright (c) 2005-2024, NumPy Developers.
20
+ Pinned `>=1.24,<3` so the random-search RNG stream stays stable for the
21
+ determinism gate. See: https://github.com/numpy/numpy
22
+
23
+ PyYAML --- YAML config parsing, via `yaml.safe_load` only (MIT License).
24
+ See: https://github.com/yaml/pyyaml
25
+
26
+
27
+ Development and Build Tooling
28
+ -----------------------------
29
+
30
+ Used to test, lint, type-check, and build the project; NOT redistributed in the
31
+ runtime wheel.
32
+
33
+ pytest (MIT) --- test runner.
34
+ hypothesis (MPL-2.0) --- property-based testing.
35
+ ruff (MIT) --- linter and formatter.
36
+ pyright (MIT) --- static type checker.
37
+ import-linter (BSD-2-Clause) --- enforces the hexagonal dependency contracts
38
+ declared in `.importlinter`.
39
+ hatchling (MIT) --- PEP 517 build backend.
40
+
41
+
42
+ Optional Extras (not installed by default)
43
+ ------------------------------------------
44
+
45
+ Declared in pyproject.toml under [project.optional-dependencies] and pulled in
46
+ only when the matching extra is requested. Each retains its upstream license;
47
+ none is bundled in the default distribution. These are integration points for
48
+ later phases and are not consumed by any Phase 1A public API.
49
+
50
+ optuna (MIT) --- `[optuna]`, Phase 2 (OptunaStrategy).
51
+ openevolve --- `[evolve]`, Plan 1B (the evolve strategy is our orchestration
52
+ over OpenEvolve's loop).
53
+ paramiko, huggingface_hub, docker --- `[backends]`, Plan 1B (SSH / Hugging Face
54
+ Jobs / Docker compute backends).
55
+
56
+
57
+ Mathematical / Methodological References
58
+ ----------------------------------------
59
+
60
+ The built-in random-search strategy (ruthless/strategies/random_/) implements
61
+ the baseline described in: Bergstra, J., & Bengio, Y. (2012). "Random Search
62
+ for Hyper-Parameter Optimization." Journal of Machine Learning Research, 13,
63
+ 281-305.
64
+
65
+ The log-uniform sampling option (the `log` flag on FloatRange in
66
+ ruthless/config.py) follows the convention popularised by Optuna's
67
+ `suggest_float(log=True)`: Akiba, T., Sano, S., Yanase, T., Ohta, T., &
68
+ Koyama, M. (2019). "Optuna: A Next-generation Hyperparameter Optimization
69
+ Framework." Proc. KDD '19. (Optuna itself is an optional Phase 2 extra, not a
70
+ Phase 1A dependency.)
71
+
72
+ The ports-and-adapters ("hexagonal") structure of the core follows: Cockburn,
73
+ A. (2005). "Hexagonal Architecture" (alistair.cockburn.us/hexagonal-architecture).
74
+ The one-way core/strategy/backend dependency direction is enforced in CI by
75
+ import-linter.
76
+
77
+
78
+ Documentation Tooling
79
+ ---------------------
80
+
81
+ The C4 architecture diagram (docs/c4/architecture.html) is authored in
82
+ Structurizr DSL (docs/c4/architecture.dsl) and rendered locally via Structurizr
83
+ and PlantUML. These tools are used only to produce the documentation artifact
84
+ and are not part of the project's dependencies.
85
+
86
+
87
+ Assets and Cultural Attribution
88
+ -------------------------------
89
+
90
+ The hero image (assets/ruthless-efficiency.jpg) and the project name/tagline
91
+ ("Our chief weapons are Ruthless Efficiency!") are an affectionate homage to
92
+ Monty Python's "The Spanish Inquisition" sketch (Monty Python's Flying Circus,
93
+ 1970). No affiliation with or endorsement by the rights holders is implied.