This release is a pre-release and may not be stable for production use.
RKO
A domain-neutral random-key optimization library with cooperating metaheuristics, inspired by RKO C++ v2. You provide a decoder and an objective to minimize; RKO searches for good key vectors without assuming a problem format or solution representation.
What you implement
For optimization, you provide the data reader, decoder and objective function.
You may also provide validate for optional post-solve checks. RKO provides the
optimization algorithms; all of these are ordinary Python functions.
| Your code | Responsibility |
|---|---|
read_data(source) |
Read your instance and return the data needed by your problem. Skip this function if the data is already in memory. |
decoder(keys) |
Use the loaded data to convert a key vector into your domain solution. |
objective(solution) |
Use the loaded data to return a finite scalar to minimize. This callable is passed as cost in the library API. |
validate(solution) (optional) |
Check your domain constraints after solving and return a ValidationReport. Omit it if you do not need final-solution checking. |
Load the data once in your application, then bind it to the decoder and objective.
RKO calls those two callbacks during search; it does not invoke read_data.
Function names are yours to choose. Module-level functions with functools.partial
or methods holding the data both work; an adapter class is optional, not a
required interface. Optional validation uses the Python API assess_result(...),
not a CLI-only feature; it runs outside the search budget and never implicitly
reevaluates the objective.
You do not need to implement a metaheuristic, population, elite pool, local
search, shaking or Q-learning controller. Select an algorithm and configure values
such as n_variables, time_limit and random_state; the library supplies the
search machinery and default operators. Custom operators are advanced overrides,
not prerequisites. See the complete data-loading example.
What it provides
- Configurable portfolios: BRKGA, BRKGA-CS, GA, GRASP, ILS, IPR, LNS, MultiStart, PSO, SA and VNS; the packaged default selects ten algorithms.
- Sequential, thread and process execution on the Python engine with shared elites, owned library RNG streams, validated parameters and immutable result metadata.
- An optional compiled Rust engine (
engine="rust") that runs the same eleven algorithms and TOML configuration. Define the problem as Python callbacks (rko_solver.Callbacks), a NumPy block objective (rko_solver.Blocks), a Numba-compiled objective (rko_solver.Numba, evaluated without the interpreter lock) or a built-in problem (rko_solver.problems);engine="auto"picks the engine for your problem by short probes. See Rust and C++ engines. - Python callbacks for arbitrary problems; NumPy is the only required runtime dependency
(Numba is optional:
pip install "rko-solver[compiled]"). Installing a prebuilt wheel needs no compiler; building from source needs a Rust toolchain. No C++ installation or agent framework is required.
Install from source
Requires Python 3.14+, uv and a Rust toolchain (the native extension is built from source). CI currently tests Python 3.14 on Ubuntu, Windows and macOS (x86_64 and ARM); other combinations are not certified by that matrix.
git clone https://github.com/MarcosPTProenca/rko-solver.git
cd rko-solver
uv sync --locked --no-dev
Run Python scripts with uv run --locked --no-dev python your_script.py from
this checkout. For reproducible use, record the Git revision as well as the lock
file.
First solve
This complete Python example loads a small instance, binds its data to your functions, solves, and optionally checks the returned solution. No CLI or adapter class is required. Replace the example's file format and domain logic with yours.
Save this as instance.json in the repository root:
{
"lower": [-5.0, -5.0, -5.0],
"upper": [5.0, 5.0, 5.0],
"target": [1.0, -2.0, 0.5]
}
Save this as quickstart.py beside it:
import json
import numpy as np
from functools import partial
from pathlib import Path
from rko_solver import RKO
from rko_solver import ValidationCheck
from rko_solver import ValidationReport
from rko_solver import assess_result
def read_data(path: Path) -> dict[str, np.ndarray]:
"""Load the example's bounds and target once before searching.
Args:
path (Path): UTF-8 JSON instance file.
Returns:
dict[str, np.ndarray]: Equal-length lower, upper and target vectors.
Raises:
OSError: If the file cannot be read.
ValueError: If JSON, fields, dimensions or bounds are invalid.
TypeError: If values cannot be converted into numerical arrays.
"""
raw = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(raw, dict) or set(raw) != {"lower", "upper", "target"}:
raise ValueError("Expected lower, upper and target fields.")
data = {name: np.asarray(value, dtype=float) for name, value in raw.items()}
shape = data["lower"].shape
if data["lower"].ndim != 1 or data["lower"].size == 0 or any(
value.shape != shape or not np.isfinite(value).all() for value in data.values()
):
raise ValueError("Expected nonempty, equal-length finite vectors.")
if np.any(data["lower"] >= data["upper"]):
raise ValueError("Each lower bound must be smaller than its upper bound.")
return data
def decoder(keys: np.ndarray, *, data: dict[str, np.ndarray]) -> np.ndarray:
"""Map random keys into the loaded variable bounds.
Args:
keys (np.ndarray): Random-key chromosome.
data (dict[str, np.ndarray]): Loaded instance data, bound before search.
Returns:
np.ndarray: Decoded numerical solution.
"""
return data["lower"] + (data["upper"] - data["lower"]) * keys
def objective(solution: np.ndarray, *, data: dict[str, np.ndarray]) -> float:
"""Minimize squared distance to the loaded target.
Args:
solution (np.ndarray): Decoded numerical solution.
data (dict[str, np.ndarray]): Loaded instance data, bound before search.
Returns:
float: Finite objective for this example's input.
"""
difference = solution - data["target"]
return float(np.dot(difference, difference))
def validate(solution: np.ndarray, *, data: dict[str, np.ndarray]) -> ValidationReport:
"""Optionally check final dimensions, finiteness and domain bounds.
Args:
solution (np.ndarray): Post-run reconstructed solution.
data (dict[str, np.ndarray]): Same loaded instance used during search.
Returns:
ValidationReport: Declared feasibility for the implemented bound checks.
"""
valid = solution.shape == data["lower"].shape and bool(
np.isfinite(solution).all()
and np.all(solution >= data["lower"])
and np.all(solution <= data["upper"])
)
return ValidationReport(
checks=(ValidationCheck(
"variable_bounds", "passed" if valid else "failed",
message="Check the declared shape, finite values and variable bounds.",
),),
feasible=valid,
)
def main() -> None:
"""Load once, optimize with data-bound callbacks, then optionally validate.
Raises:
OSError: If the instance cannot be read.
ValueError: If the input or solver settings are invalid.
TypeError: If instance values are not numerical.
"""
data = read_data(Path("instance.json"))
decode = partial(decoder, data=data)
cost = partial(objective, data=data)
solver = RKO(
decoder=decode, cost=cost, n_variables=data["lower"].size,
algorithms=["SA", "PSO"], adaptation="fixed",
hyperparameters={
"SA": {"sa_max": 100, "t0": 1000.0, "alpha": 0.98},
"PSO": {"p_size": 20, "c1": 1.5, "c2": 1.5, "w": 0.6},
},
execution="sequential", random_state=42,
)
result = solver.solve(time_limit=1.0)
assessment = assess_result(
result, decoder=decode, validator=partial(validate, data=data),
)
print("Solution:", assessment.solution)
print("Objective:", result.cost)
print("Validation:", assessment.validation.status)
print("Evaluations:", result.n_evaluations)
if __name__ == "__main__":
main()
Run uv run --locked --no-dev python quickstart.py from that directory.
The wiring is explicit:
data = read_data(...)runs in your application before constructing RKO.partial(decoder, data=data)andpartial(objective, data=data)bind loaded data to the callbacks passed toRKO(decoder=..., cost=...).solver.solve(...)runs the selected metaheuristics using those callbacks.assess_result(..., validator=partial(validate, data=data))optionally checks the post-run solution. Neitherread_datanorvalidateruns inside search.
To skip validation, omit validate and all assessment-related lines. Use
solution = decode(np.asarray(result.keys)) and print that solution instead.
Assessment validates a post-run reconstruction, not optimality or an original
execution witness. See validation details.
The decoder receives a one-dimensional NumPy key vector; the objective must
return a finite scalar to minimize. Readers and feasibility logic belong in
your problem adapter. random_state owns library draws, not randomness inside
user callbacks; timed runs can still differ because of scheduling.
The main API is RKO(...): the example runs a cooperating SA/PSO portfolio with
shared elites. It explicitly selects sequential execution for a simple first run.
RKO's default is a process portfolio: use importable callbacks and a guarded entry point
as shown in the process-safe example.
Sequential execution gives each selected algorithm its own search allowance; process
startup is excluded, and opted-in pool prefill has a separate allowance. A callback
can overrun its deadline. time_limit is not a hard end-to-end timeout.
Run one metaheuristic instead
Keep read_data, the data-bound decode/cost functions and optional assessment
unchanged. Replace only the solver block inside main.
Through the main RKO API, select one algorithm:
solver = RKO(
decoder=decode, cost=cost, n_variables=data["lower"].size,
algorithms=["SA"], adaptation="fixed", execution="sequential", random_state=42,
hyperparameters={"SA": {"sa_max": 100, "t0": 1000.0, "alpha": 0.98}},
)
result = solver.solve(time_limit=1.0)
Through the direct algorithm API, import SA from rko_solver.metaheuristics
alongside the other imports, then use:
solver = SA(
decoder=decode, cost=cost, n_variables=data["lower"].size,
adaptation="fixed", execution="sequential", random_state=42,
hyperparameters={"SA": {"sa_max": 100, "t0": 1000.0, "alpha": 0.98}},
)
result = solver.solve(time_limit=1.0)
Both forms use the same configure-then-solve lifecycle and return RKOResult.
SA selects SA automatically; PSO, GRASP and the other
built-in classes select their own algorithm.
They inherit RKO's execution, stopping, RNG ownership, history and result_ behavior.
The examples explicitly select sequential execution; all public solvers otherwise share
RKO's default process execution and configured adaptation mode.
Algorithm hyperparameters
hyperparameters is an explicit constructor parameter for both RKO and the
individual solver classes. Use the same nested dictionary: algorithm name -> scalar
overrides. It controls the algorithm itself, not worker or engine settings. Only keys
you provide replace defaults; manual scalar overrides require adaptation="fixed".
| Algorithm | Configurable scalar keys |
|---|---|
| SA | sa_max, t0, alpha, beta_min, beta_max |
| ILS | beta_min, beta_max |
| VNS | k_max, beta_min |
| LNS | beta_min, beta_max, t0, alpha_lns |
| BRKGA / BRKGA-CS | p, pe, pm, rhoe |
GA (GeneticAlgorithm) |
size_pop, prob_cros, prob_mut |
| PSO | p_size, c1, c2, w |
| GRASP | hs, he |
| IPR / MultiStart | No configurable search scalars |
See the parameter reference for meanings, defaults, joint
constraints and adaptive grids. Some identically named keys have different meanings
between algorithms (notably BRKGA versus BRKGA-CS pm); do not copy interpretations
blindly. Each dictionary entry must name an algorithm actually selected by the solver.
Use your own instance data
The application loads data once before searching and binds it to the decoder and objective. Metaheuristics do not need their own file readers:
your read_data(path) -> loaded data
-> your decoder + objective (data bound once)
-> chosen algorithm or RKO (provided by the library)
-> best keys -> explicit final decoding
A complete file-to-solution tutorial shows a JSON
scheduling instance where the decoder uses loaded processing times and the objective
uses loaded due dates. The tutorial groups these two callbacks in an importable
class for convenience; you can use functions instead. The same callbacks work
unchanged with SA(...).solve(...), other built-in classes and RKO portfolios. There is
no required base class.
Run the packaged example without creating an input file:
uv run --locked --no-dev python -m rko_solver.examples.instance_pipeline
For your own file, use the tutorial's schema or replace its reader/adapter with your
application's format. Loading once does not mean shared RAM across process workers;
keep callbacks pickleable and account for copied data when choosing n_jobs.
Interactive analysis reports
Install the optional reporting dependency with uv sync --locked --extra reports.
To plot convergence, add history_limit=1000 to the solve call above. Import
OptimizationReport from rko_solver.reporting alongside your other imports, then add
this after assessment inside main:
report = OptimizationReport(result, assessment=assessment)
report.write_html("run.html")
report.write_json("run.json")
If you skipped optional validation, use OptimizationReport(result) instead.
The HTML embeds Plotly once and works offline with hover, zoom and trace selection. Reports are generated after search, never by reevaluating callbacks. History is off by default; compacted curves are labelled approximate. See interpretation and privacy boundaries; automatic PDF export is not included. Core optimization still requires only NumPy.
Reports can optionally include an author-declared or source-derived decoder
diagram, explicitly attached through decoder_diagram.
Source inspection never runs automatically and static structure is not an execution
trace, a complete explanation or a feasibility/optimality certificate.
Bounded mathematical models (development port)
The optional Pyomo, PuLP and MathOpt model converter is being ported to this repository. It generates owned sparse callbacks with bounded continuous feasibility restoration and independent feasible-witness evidence.
import importlib.util
from rko_solver import RKO
if importlib.util.find_spec("pyomo") is not None:
import pyomo.environ as p
model = p.ConcreteModel()
model.x = p.Var(bounds=(0, 1))
model.y = p.Var(bounds=(0, 1))
model.balance = p.Constraint(expr=model.x + model.y == 1)
model.objective = p.Objective(expr=model.x + 2 * model.y)
solver = RKO.from_model(model, engine="python", execution="sequential", repair="continuous")
result = solver.solve(0.1)
print(result.model.status)
else:
print("Install rko-solver[pyomo] to run this optional example.")
Install the matching extra (rko-solver[pyomo], [pulp] or [mathopt]). Integer
choices remain fixed during repair; this is not a complete MILP feasibility solver.
repair="none" retains box-only mapping. Rust/C++/automatic engine selection is
not supported for this factory because those paths lack its model-witness contract.
Model contracts and historical qualification distinguish prior measurements from this renamed port. Local feature tests and mandatory quality ratchets pass; fresh hosted-platform, artifact and performance qualification remain pending.
Optional observed decoder decisions
To retain decisions from the original evaluated decoder invocation, explicitly
emit record_decision(action, reason) inside your decoder and opt in with
RKO(..., trace=TraceConfig()), importing both helpers from rko_solver.tracing.
Existing callback signatures and uninstrumented usage remain unchanged.
Try the instrumented scheduling adapter and its optional offline report:
uv run --locked python -m rko_solver.examples.decision_trace
uv run --locked --extra reports python -m rko_solver.examples.decision_trace --html results/observed-decisions.html
result.trace distinguishes recorded, no-events, truncated and unavailable evidence.
Recording is bounded and off by default; it can be expensive for cheap callbacks and
uses the existing search budget. The engine never replays callbacks or borrows a
matching keys/cost trace when evaluation identity is lost. Observations are partial
author-emitted decisions, not static flowcharts, complete execution logs or
feasibility proofs. See the instrumentation, identity, privacy and overhead
guide before enabling it or sharing event text.
Optional private FastAPI/Docker service
Expose your existing decoder/objective and optional checker through an authenticated HTTP API without rewriting the solver. The maintained reference includes a trusted scheduling adapter, supervised job cancellation/timeouts, offline report downloads and a resource-limited Docker Compose configuration. HTTP dependencies remain optional; core optimization still requires only NumPy.
From the reviewed source checkout, build the SDK and generate a new service project.
Set SDK_WHEEL to the actual absolute path of the wheel just built in dist/;
do not assume an older PyPI release contains this API. The destination must not exist.
A working Docker Linux engine and Docker Compose are required.
uv sync --locked --extra service --extra reports
uv build --wheel
SDK_WHEEL=/absolute/path/to/the-reviewed-rko-wheel.whl
uv run --locked rko-solver-service scaffold ../my-private-service --wheel "$SDK_WHEEL"
cd ../my-private-service
export RKO_WHEEL="${SDK_WHEEL##*/}"
export RKO_SERVICE_API_KEY="$(uv run --no-project python -c 'import secrets; print(secrets.token_urlsafe(32))')"
docker compose up --build -d
curl --fail http://127.0.0.1:8000/health
Submit bounded JSON to the reference adapter using the generated bearer secret:
curl --fail http://127.0.0.1:8000/jobs \
-H "Authorization: Bearer $RKO_SERVICE_API_KEY" -H 'Content-Type: application/json' \
-d '{"instance":{"name":"demo","processing_times":[3,2,5],"due_dates":[3,6,9]},"options":{"algorithms":["SA","PSO"],"time_limit":0.2,"validate_solution":true,"include_solution":true,"report":true}}'
The response contains a job UUID; poll authenticated GET /jobs/UUID for its result.
Edit the generated adapter.py to bind your application's bounded schema and trusted
callbacks. Clients submit data/settings, never Python code, imports or host paths.
This is a private single-tenant Linux-container reference, not a public SaaS or
an untrusted-code sandbox. Keep the supplied localhost binding, authentication and
CPU/RAM/PID/disk limits. Only one job runs at a time; results expire and container
replacement can erase them. Native Windows supervision is unsupported; Windows/WSL
hosts use Linux Docker. Stop the reference with docker compose down.
See the complete FastAPI/Docker guide for integration, API endpoints,
cancellation, retention, resource limits and deployment/security requirements.
Run the supplied Knapsack adapter
uv run --locked --no-dev rko-solver src/rko_solver/examples/instances/kp50.txt \
--limit-time 10 --execution process --random-state 42 \
--output-csv results/kp50.csv
The supplied command handles Knapsack, not arbitrary input formats. Its two bundled instances are correctness fixtures, not competitive-performance evidence. See terminal/configuration usage for custom instances, TOMLs, progress output and worker limits.
Documentation
Start at the documentation index: tutorials, how-to guides, parameter reference and contributor guidance.
| Need | Guide |
|---|---|
| Solve your first problem | Getting started |
| Use any one algorithm without managing a pool | Standalone algorithms |
| Load instance data and implement decoder/objective callbacks | File-to-solution tutorial |
| Understand fixed/adaptive modes and every search knob | Parameter reference |
| Replace operators or implement an algorithm | Extension guide |
| Generate offline interactive HTML charts and data-only exports | Analysis reports |
| Optionally check the final domain solution | Post-solve validation |
| Optionally illustrate decoder logic without executing it | Static decoder diagrams |
| Record bounded author-emitted decisions from an original evaluation | Observed decoder decisions |
| Connect trusted callbacks to a bounded private HTTP container | Optional FastAPI/Docker service |
| Preview/build the development documentation website | Documentation website |
| Configure the solver, callbacks, hyperparameters and results | Usage and API guide |
| Choose workers and understand startup/time accounting | Execution modes, workers, startup |
| Run from the terminal or avoid WSL setup overhead | Running guide |
| Use the compiled engines and built-in problems | Rust and C++ engines |
| Understand the C++ target and native-engine evidence | Performance and native-engine evaluation |
| Inspect measurements rather than speed claims | Benchmarks, expanded quality study |
| Check algorithm differences and remaining risks | C++ compatibility, current limitations |
| See how the API, the three engines and the folders fit together | Architecture |
| Develop, test or report an issue | Contributing |
engine selects the Python, Rust or C++ engine (or "auto"), and execution selects
process, thread or sequential scheduling for the Python engine. Rust results versus pinned C++ and Python are reported with
their limits in benchmarks;
they do not extend to untested problem families, budgets or hardware. Prefill remains
opt-in: broader IPR benefits include regressions, and large-GRASP short-budget wins
can be startup-only.
Project status and attribution
Version 0.3.0a4 is a prerelease, not a stable release. Matching or exceeding C++ RKO is a
performance target, not an achieved claim; read the limitations
and C++ compatibility before relying on it.
Wheel/sdist installation and the full test suite are checked on Ubuntu, Windows and macOS;
that is not a supported-version or release guarantee.
The LICENSE (Apache-2.0) applies. NOTICE lists the required attributions and the fixture and vendored C++ licenses. New third-party additions and every publication still require review and approval. Report reproducible bugs through GitHub issues.
Metadata
Release files for rko-solver 0.3.0a4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rko_solver-0.3.0a4.tar.gz | 419.1 kB | With provenance | Details for rko_solver-0.3.0a4.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| rko_solver-0.3.0a4-cp314-abi3-win_arm64.whl | CPython 3.14 | abi3 | Windows ARM64 | Details for rko_solver-0.3.0a4-cp314-abi3-win_arm64.whl |
| rko_solver-0.3.0a4-cp314-abi3-win_amd64.whl | CPython 3.14 | abi3 | Windows x86-64 | Details for rko_solver-0.3.0a4-cp314-abi3-win_amd64.whl |
| rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_x86_64.whl | CPython 3.14 | abi3 | Linux glibc 2.28+ x86-64 | Details for rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_x86_64.whl |
| rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_aarch64.whl | CPython 3.14 | abi3 | Linux glibc 2.28+ ARM64 | Details for rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_aarch64.whl |
| rko_solver-0.3.0a4-cp314-abi3-macosx_11_0_arm64.whl | CPython 3.14 | abi3 | macOS 11.0+ ARM64 | Details for rko_solver-0.3.0a4-cp314-abi3-macosx_11_0_arm64.whl |
| rko_solver-0.3.0a4-cp314-abi3-macosx_10_12_x86_64.whl | CPython 3.14 | abi3 | macOS 10.12+ x86-64 | Details for rko_solver-0.3.0a4-cp314-abi3-macosx_10_12_x86_64.whl |
Total release size: 5.3 MB
Release files / rko_solver-0.3.0a4.tar.gz
| Download URL | rko_solver-0.3.0a4.tar.gz |
|---|---|
| Size | 419.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
27d6d9c1c706212c3c06d6c904c2f60a3668289f9bac9a973f169713bb5b8f08
|
|
BLAKE2b-256 checksum How to use checksums |
e6645da05ffcedac5f8fd2360efc963ddf398564d56845d82f4d9ae4738aa69a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-win_arm64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-win_arm64.whl |
|---|---|
| Size | 669.6 kB |
| Tags | CPython 3.14 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
3d3b6e15360f61e6b2ddf90bc9f2a760a8ac2731549583584848f0f5ba6a5089
|
|
BLAKE2b-256 checksum How to use checksums |
6e6b489739a925660b6e3c27d09f7e26935d02112850131b27a456f12847a991
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-win_amd64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-win_amd64.whl |
|---|---|
| Size | 688.6 kB |
| Tags | CPython 3.14 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
3916b82faf2c19e994194d515c8df6b3fd514f836ec276f6f88577ac1d89eb74
|
|
BLAKE2b-256 checksum How to use checksums |
66857d1dab20603ab296f808511e3e8e6ee3fdb516f18aff82c529994ee12d18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_x86_64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 999.5 kB |
| Tags | CPython 3.14 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
25447c9f14a11ea145fd698bf86e069a083dec522f6e1adb44462b163564fa69
|
|
BLAKE2b-256 checksum How to use checksums |
85fbbe890f2d38da679fc1607194e9a53dfc8cdcfb2704772ae9f95d4c610b8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_aarch64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 982.2 kB |
| Tags | CPython 3.14 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
4b2c3d4b0f902b16198a145ccdf0ebbb02cab264221926a65cdb1278c1b01624
|
|
BLAKE2b-256 checksum How to use checksums |
ae990f0a525a2ea6e7845f786526d15540d1364b84631133ce92f9b4c250d066
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-macosx_11_0_arm64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 763.5 kB |
| Tags | CPython 3.14 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2d29da63472bd6e0ca10b49f98f32c63d30de9ad88559e2b1f9380f5cee5dd95
|
|
BLAKE2b-256 checksum How to use checksums |
2143855ac3e1d725c7d3e49a2c0dbf767062e3d94e2fe3d885370903a22caa60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logRelease files / rko_solver-0.3.0a4-cp314-abi3-macosx_10_12_x86_64.whl
| Download URL | rko_solver-0.3.0a4-cp314-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 780.5 kB |
| Tags | CPython 3.14 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
74060b072305390dd666b62a51051bd87a2c786db37ffada979c0d64d40dd146
|
|
BLAKE2b-256 checksum How to use checksums |
9b24d9029bb569585a331aea4b284a48eeae56322603203f42f6c5a5f90b4323
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logSecurity for rko-solver 0.3.0a4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 7 files in this release have been uploaded with provenance metadata.
Attestation for rko_solver-0.3.0a4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.