rill-ml 1.3.0

RillML adaptive intelligence core library — lightweight, serializable online machine learning for native and edge applications.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
<p align="center">
  <img src="logo.png" alt="RillML" width="480">
</p>

<p align="center">
  <strong>RillML (Rill)</strong> is a lightweight adaptive intelligence runtime for native and edge applications.
</p>

<p align="center">
  It combines online machine learning, bounded adaptation, stable runtime protocols, signed model/handler assets, and safe host integration for continuously changing systems.
</p>

<p align="center">
  <a href="https://github.com/hello-yunshu/rill-ml/actions/workflows/pipeline.yml"><img src="https://github.com/hello-yunshu/rill-ml/actions/workflows/pipeline.yml/badge.svg" alt="CI / Release"></a>
  <a href="https://crates.io/crates/rill-ml"><img src="https://img.shields.io/crates/v/rill-ml.svg" alt="crates.io"></a>
  <a href="https://docs.rs/rill-ml"><img src="https://docs.rs/rill-ml/badge.svg" alt="docs.rs"></a>
  <a href="LICENSE-MIT"><img src="https://img.shields.io/crates/l/rill-ml.svg" alt="License: MIT"></a>
  <img src="https://img.shields.io/badge/rust-1.94%2B-orange.svg" alt="Rust 1.94+">
</p>

<p align="center">
  <a href="README.md">中文</a> &middot; <a href="CHANGELOG.md">Changelog</a> &middot; <a href="ROADMAP.md">Roadmap</a> &middot; <a href="PLATFORM_SUPPORT.md">Platform Support</a> &middot; <a href="https://docs.rs/rill-ml">API Docs</a>
</p>

---

## 1. What is RillML

**RillML** (referred to as **Rill** where the context is unambiguous) is a lightweight adaptive intelligence runtime for native and edge applications.

It is not "just another online machine learning library". It combines the following capabilities into a single independently distributable runtime:

- **Online ML core**: statistics, regression/classification, drift detection, multi-armed bandits and decision primitives, all implemented in pure safe Rust with bounded state;
- **RillML Runtime (`rill-runtime`)**: a standalone local inference runtime that loads signature-verified WASM handlers in a sandbox, so hosts can integrate safely without linking the engine;
- **Signed assets**: `.rillpack` model packs, `.rillhandler` handler packs and the Ed25519-signed release index, so every update is verifiable and rollback-able;
- **Stable protocol boundaries**: `rill-runtime-protocol` provides frozen v1/v2 JSON IPC; `rill-handler-api` provides the frozen v1 WIT ABI;
- **Safe host integration**: models and handlers can never modify host state directly; all system changes belong to the host governance layer.

The production Runtime CLI accepts Stable IPC v1/v2 only. Preview IPC v3 is
currently **library-only** and is not exposed as a production CLI/subprocess
entrypoint. `serve` requires an explicit signed `--handler` or the deprecated
`--builtin-handler linear-regression`; omitting both fails closed rather than
silently falling back.

The workspace also includes a separately distributable `rill-runtime`, a stable IPC contract, signed `.rillpack` model packages, and signed `.rillhandler` WASM handler packages. The runtime loads signature-verified WASM handlers in a sandbox; updating a handler no longer requires recompiling the runtime binary. Hosts can compile only the protocol crate and update the runtime, models, and handlers independently from the main application. Official macOS Runtime releases support Apple Silicon (ARM64) only; no Intel build is provided. The macOS aarch64 asset is unsigned — the project does not configure an Apple Developer ID certificate, and this is a permanent decision that does not block any release. macOS users may need to authorize first launch through standard controls such as Finder right-click → Open or System Settings → Privacy & Security; see [`STABILITY.md`](STABILITY.md) § macOS unsigned policy for details. The 1.0 stability matrix, frozen surface, and Stable/Preview split are documented in [`STABILITY.md`](STABILITY.md); see [`RUNTIME.md`](RUNTIME.md) for the runtime product and release boundary.

> RillML is inspired by the online-learning workflow popularized by [River](https://riverml.xyz/). It is an independent Rust project and is not affiliated with or endorsed by River. It does not currently aim for API or model compatibility.

## 2. Why RillML

### Why online learning?

Traditional machine learning follows a batch workflow: collect data, train offline, deploy a fixed model, and periodically retrain. This works well when data is abundant, static, and centrally available.

Online learning takes a different approach: **process one sample at a time, predict before learning, and adapt continuously**. This is well-suited for:

- **Streaming data** — you cannot store all history.
- **Edge devices** — limited memory, no Python runtime.
- **Continuously changing environments** — a fixed model goes stale.
- **Privacy-sensitive scenarios** — data should not leave the device.
- **Real-time systems** — predictions needed before the next sample arrives.

RillML implements this workflow in pure, safe Rust; fixed-dimension algorithms use bounded state, while dynamic-feature algorithms such as FTRL require `max_features` to be set for bounded state.

### Suitable scenarios

- Online regression for IoT telemetry, resource usage, or sensor readings.
- Sensor anomaly detection with rolling statistics.
- Real-time click or event classification.
- Network latency prediction with concept drift.
- Any Rust application that needs a lightweight, always-on learning component.

**Non-suitable scenarios:** Large-scale offline training (use Linfa/SmartCore/Python), deep learning (use Burn/candle/tch-rs), distributed training, GPU acceleration, research experimentation (Python is better suited). Rust does not make the same algorithm inherently more accurate; the value comes from engineering deployment, state management, and local execution.

### Product boundary

RillML's core value is not "the most algorithms", but:

```text
online adaptation
bounded resource usage
native/edge deployment
stable protocol boundaries
signed artifacts
safe runtime execution
state lifecycle
feedback/outcome loop
drift handling
decision primitives
product integration
```

Relationship to River:

```text
River   = broad online ML algorithms / experimentation ecosystem
RillML  = production-oriented adaptive intelligence runtime for native and edge systems
```

River can be used as a reference, baseline, and offline validation source, but Python is never introduced as a production dependency on target devices.

## 3. Core capabilities

### Module overview

| Category | Modules |
|---|---|
| Statistics | Mean, Variance, Std, Count, Sum, Min, Max, EWMean, RollingMean, RollingVariance, P2Quantile, ClippedMean, bounded RollingMedianMad/modified-z, weighted statistics |
| Preprocessing | StandardScaler, MinMaxScaler, Clipper, OneHotEncoder, OrdinalEncoder, FrequencyEncoder, MissingIndicator, ConstantImputer, MeanImputer, ForwardFill |
| Sparse features | SparseFeatures, FeatureHasher |
| Models | LinearRegression, LogisticRegression, MeanRegressor, EWMeanRegressor, LastValueRegressor, FtrlRegressor, FtrlClassifier, GaussianNaiveBayes, BernoulliNaiveBayes, MultinomialNaiveBayes |
| Optimizers | SGD (with L2), AdaGrad |
| Losses | SquaredError, HuberLoss, BinaryLogLoss |
| Metrics (regression) | MAE, MSE, RMSE, R², RollingMAE, RollingMSE |
| Metrics (classification) | Accuracy, Precision, Recall, F1, LogLoss, RollingAccuracy |
| Pipelines | RegressionPipeline, ClassificationPipeline |
| Evaluation | Progressive evaluation (predict → metric → learn) |
| Persistence | `Snapshot<T>` with versioned envelope (serde feature) |
| Diagnostics | TrainingSummary, WarmupTracker, BaselineComparator, OnlineModelSelector, ResidualInterval, ModelHealthReport, PredictionReporter |
| Drift detection | PageHinkley, Adwin, Kswin, portable state V1, DriftConsensus, DriftAwareModel, DriftAction, DriftStrategy |
| Online decision-making | EpsilonGreedy, Ucb1, ThompsonSampling, LinUcb score breakdown, Preview LinUcbFast, DecisionLedger, DecisionReplayHarness |
| Identity and weights | FeatureSchema, ModelDescriptor, WeightedStatistic/Regressor/Classifier |

**Memory bounds:** Non-rolling statistics O(1); linear models O(d); rolling statistics O(window_size); sparse models (FTRL) O(k), k = seen feature count (unbounded by default; set `max_features` to bound); drift detectors O(1) or O(window_size); LinUCB O(arm_count × d²).

FTRL's `resource_diagnostics()` reports the current feature count, configured
cap, saturation, and new-feature rejection signal without mutating the model.
The unbounded default preserves compatibility; long-running services that
accept untrusted or open-ended vocabularies should configure a finite
`max_features`. See [`docs/FTRL_RESOURCE_DIAGNOSTICS.md`](docs/FTRL_RESOURCE_DIAGNOSTICS.md).

Delayed feedback uses a caller-owned clock, explicit model generations,
bounded pending/completed storage, and exact replay semantics; `DecisionLedger`
never silently evicts state. See [`docs/DECISION_LEDGER_V1.md`](docs/DECISION_LEDGER_V1.md).

## 4. Architecture

RillML is uniformly expressed as three layers: the Online ML core, the Runtime, and the Integrations layer.

```text
                       RillML
                         │
          ┌──────────────┼──────────────┐
          │              │              │
       Online ML      Runtime        Integrations
          │              │              │
    statistics         IPC             PM
    regression         packs           Xray
    classification     handlers        native apps
    drift              signing
    bandits            sandbox
    decisions          state
```

Or, from the host perspective:

```text
Host Application
      │
      ▼
RillML Runtime
      │
      ├── Online ML Core
      ├── State / Snapshot
      ├── Drift / Decision
      ├── Signed Model Packs
      └── Sandboxed Handlers
```

`rill-ml` is the RillML adaptive intelligence core library; it forms the foundation of the runtime but is not the whole project.

## 5. Quick start

### Installation

```bash
cargo add rill-ml
```

For serialization support, enable the `serde` feature:

```bash
cargo add rill-ml --features serde
```

`rill-ml` enables the `bandit` feature (multi-armed bandits module, pulls in `rand`) by default;
disable it with `cargo add rill-ml --no-default-features` if not needed.

`rill-runtime` enables the `wasm` feature (Wasmtime sandbox, can load `.rillhandler` packs out
of the box) by default, so `cargo install rill-runtime` matches the official GitHub binary
behaviour. For a WASM-free build: `cargo install rill-runtime --no-default-features` (cannot
load `.rillhandler`).

The version tracks `[workspace.package].version`; query the current release via `cargo metadata`
or [`CHANGELOG.md`](CHANGELOG.md). The Stable group is currently at `1.3.0`;
the Preview group remains at `0.15.0`.

**Requirements:** Rust 1.94+ (Edition 2024), no nightly needed.

### Basic usage

```rust
use rill_ml::{
    metrics::Mae,
    models::{LinearRegression, LinearRegressionConfig},
    optim::{Optimizer, SgdConfig},
    pipeline::RegressionPipeline,
    preprocessing::StandardScaler,
    Metric, OnlineRegressor,
};

let feature_count = 2;
let scaler = StandardScaler::new(feature_count).unwrap();
let optimizer = Optimizer::sgd(
    feature_count,
    SgdConfig { learning_rate: 0.05, l2: 0.0 },
).unwrap();
let regression = LinearRegression::new(
    feature_count,
    LinearRegressionConfig { optimizer, loss: Default::default() },
).unwrap();
let mut model = RegressionPipeline::new(scaler, regression).unwrap();
let mut mae = Mae::default();

let samples = [
    ([0.1, 0.2], 0.5),
    ([0.3, 0.8], 1.4),
    ([0.6, 0.4], 1.1),
];
for (features, target) in samples {
    let prediction = model.predict(&features).unwrap();
    mae.update(target, prediction).unwrap();
    model.learn(&features, target).unwrap();
}
```

### Examples

| Example | Description | Command |
|---|---|---|
| [online_regression](examples/online_regression.rs) | Compare Mean/EWMean/LinearRegression, StandardScaler, Snapshot serialization | `cargo run --example online_regression --features serde` |
| [online_classification](examples/online_classification.rs) | Online binary classification with LogisticRegression | `cargo run --example online_classification` |
| [diagnostics_demo](examples/diagnostics_demo.rs) | TrainingSummary, PredictionReporter, OnlineModelSelector, ModelHealthReport | `cargo run --example diagnostics_demo` |
| [sparse_classification](examples/sparse_classification.rs) | SparseFeatures, FeatureHasher, FTRL, NaiveBayes high-dim sparse classification | `cargo run --example sparse_classification` |
| [drift_demo](examples/drift_demo.rs) | Page-Hinkley, ADWIN, KSWIN drift detection with DriftAwareModel | `cargo run --example drift_demo` |
| [bandit_demo](examples/bandit_demo.rs) | EpsilonGreedy, UCB1, ThompsonSampling, LinUCB online decision-making | `cargo run --example bandit_demo` |
| [sensor_stream](examples/sensor_stream.rs) | Sensor data stream online statistics | `cargo run --example sensor_stream` |
| [progressive_validation](examples/progressive_validation.rs) | Progressive evaluation flow demo | `cargo run --example progressive_validation` |

## 6. RillML Runtime

`rill-runtime` (display name **RillML Runtime**, shorthand **Rill Runtime**) is a standalone local inference product built on top of `rill-ml`. A host application only needs to compile the small `rill-runtime-protocol`; it does not link the RillML engine into itself, so the Runtime and model packs can be updated independently of the host application.

| Crate | Description | Status | Install |
|---|---|---|---|
| `rill-runtime` | Standalone executable runtime that loads signed model and handler packs | Stable | `cargo install rill-runtime` |
| `rill-runtime-protocol` | Stable, strict, versioned JSON IPC types | Stable | `cargo add rill-runtime-protocol` |
| `rill-handler-api` | Versioned WIT handler ABI contract (for handler authors) | Stable | `cargo add rill-handler-api` |

The complete runtime product boundary, IPC versions, CLI, and release contract are documented in [`RUNTIME.md`](RUNTIME.md).

## 7. Online ML

### Progressive evaluation

The core contract of online learning is: **predict before you learn**. The `evaluate` module enforces this order:

```text
predict  →  metric.update  →  learn
```

This ensures metrics reflect the model's ability to generalize to *unseen* data, not memorized samples.

```rust
use rill_ml::evaluate::{evaluate_regression, RegressionSample};
use rill_ml::metrics::Mae;
use rill_ml::models::{BaselineConfig, MeanRegressor};
use rill_ml::OnlineRegressor;

let mut model = MeanRegressor::new(BaselineConfig::default()).unwrap();
let mut mae = Mae::default();

let samples = vec![
    RegressionSample { features: vec![], target: 10.0 },
    RegressionSample { features: vec![], target: 20.0 },
    RegressionSample { features: vec![], target: 30.0 },
];

let final_mae = evaluate_regression(&mut model, &mut mae, samples).unwrap();
```

### Serialization

Enable the `serde` feature to serialize and restore model state:

```rust
use rill_ml::persistence::Snapshot;
use rill_ml::stats::Mean;
use rill_ml::OnlineStatistic;

let mut mean = Mean::new();
mean.update(1.0).unwrap();
mean.update(2.0).unwrap();

let snap = Snapshot::new(mean);
let json = serde_json::to_string(&snap).unwrap();
let restored: Snapshot<Mean> = serde_json::from_str(&json).unwrap();
let m = restored.into_model().unwrap();
assert!((m.value() - 1.5).abs() < 1e-12);
```

`Snapshot<T>` wraps model state with a format version and rejects incompatible versions. For untrusted snapshots or application-specific model constraints, use `into_model_with_validation()` to validate restored state before activation. See [`RELIABILITY.md`](RELIABILITY.md) for the complete production integration and fallback guidance.

## 8. Signed model and handler assets

RillML's model packs, handler packs, and release index are all signed, verifiable, and rollback-able:

- `.rillpack` model packs: model definition, parameters, checksum, and Ed25519 signature.
- `.rillhandler` handler packs: WASM handler module, manifest, checksum, and Ed25519 signature.
- `stable-index.json`: versions, platforms, URLs, sizes, and SHA-256 for the Runtime/models/handlers, signed by Ed25519.

Models and handlers use independent trust stores and cannot be merged automatically; model keys cannot sign handlers and vice versa. The release index signature covers the SHA-256, size, version, platform, and URL of every binary, model pack, and handler pack.

## 9. Safety model

RillML follows the principle "the more capable, the clearer the permission boundary":

- Models and handlers can never modify host state directly (no UCI writes, no sysctl writes, no firewall changes, no arbitrary command execution).
- The Runtime executes handlers inside a Wasmtime sandbox: no WASI permissions, per-call fuel budget and epoch timeout, 64 MiB memory cap, and a 1 MiB JSON I/O cap.
- Startup self-checks, signature verification, SHA-256 verification, size validation, HTTPS policy, message bounds, and fail-closed fallback are enforced across all asset loading paths.

The complete threat model and safe usage guidance are documented in [`SECURITY.md`](SECURITY.md).

## 10. Platform support

| Platform | Runtime | Core library |
|---|---|---|
| Linux x86_64 | Stable | Stable |
| Windows x86_64 | Stable | Stable |
| Windows ARM64 (aarch64) | Stable | Stable |
| macOS aarch64 (Apple Silicon) | Stable (unsigned) | Stable |
| macOS x86_64 (Intel) | Not released | Stable |

Official macOS Runtime assets are Apple Silicon (ARM64) only, under the permanent unsigned policy; Linux and Windows remain x86_64. The full matrix and Stable/Preview commitments are documented in [`PLATFORM_SUPPORT.md`](PLATFORM_SUPPORT.md).

## 11. Integrations and ecosystem

Workspace crates are split into a Stable group (under the 1.x compatibility freeze) and a Preview group (still at `0.x`). The full stability matrix and frozen surface are documented in [`STABILITY.md`](STABILITY.md). The core library does not pull in `tokio`/`arrow`/`polars`/`wasm-bindgen`/`pyo3` by default.

| Crate | Description | Status | Install |
|---|---|---|---|
| `rill-ml` | RillML adaptive intelligence core library (the subject of this document) | Stable | `cargo add rill-ml` |
| `rill-ml-tokio` | Drives `predict → metric → learn` over a `tokio_stream::Stream` | Preview | `cargo add rill-ml-tokio` |
| `rill-ml-arrow` | Convert between Apache Arrow `RecordBatch`/`Float64Array` and `&[f64]` | Preview | `cargo add rill-ml-arrow` |
| `rill-ml-polars` | Convert between Polars `DataFrame` and sample pairs; append prediction column | Preview | `cargo add rill-ml-polars` |
| `rill-ml-wasm` | WebAssembly bindings (`wasm32-unknown-unknown`) for browser-side online learning | Preview | `cargo add rill-ml-wasm` |
| `rill-ml-python` | Python bindings (PyO3 + Maturin); PyPI package `rill-ml-python`, `import rill_ml` | Preview | `pip install rill-ml-python` |
| `rillml-inspect` | CLI to view `Snapshot` JSON, version, and validation status (not a runtime dependency) | Preview | `cargo install rillml-inspect` |
| `rill-ml-ffi` | Stable C ABI (opaque handle + `rill_ml.h`) for C/C++, Android (JNI), iOS (Swift) | Preview | `cargo add rill-ml-ffi` |
| `rill-pm-adapter` | `pm-rill-shadow` v1 decision adapter for the OpenWrt Performance Manager (advisory only; does not compile RillML) | Preview | — |

### Related projects

| Project | Focus | Relationship to RillML |
|---|---|---|
| [River](https://riverml.xyz/) | Python online learning | RillML is inspired by its workflow, independently implemented, no compatibility target |
| [Linfa](https://github.com/rust-ml/linfa) | Rust batch learning toolkit | Batch-focused; RillML focuses on online/incremental learning |
| [SmartCore](https://smartcorelib.org/) | Rust ML library | Primarily batch-oriented; RillML targets streaming and edge deployment |
| [Burn](https://burn-rs.github.io/) | Rust deep learning framework | Targets neural networks and GPU; RillML targets lightweight online models |

These projects are complementary, not competitive.

## 12. Stability

RillML is under the 1.x Stable compatibility commitment. The following contracts remain frozen within 1.x:

```text
rill-ml Rust public API
selected serde model state
rill-runtime-protocol IPC v1/v2
rill-handler-api WIT ABI v1
rill-runtime public API / CLI
.rillpack format v1
.rillhandler format v1
stable release-index contract
```

Stable crate public APIs are recorded in `api-baseline/` and enforced by `cargo-semver-checks` in CI. Do not force a 2.0 for positioning/documentation upgrades: only a real API / ABI / wire / state schema breaking change warrants 2.0. The full policy is documented in [`STABILITY.md`](STABILITY.md).

## 13. Roadmap

RillML follows a real-need-driven roadmap. See [`ROADMAP.md`](ROADMAP.md) for the full plan and [`STABILITY.md`](STABILITY.md) for the 1.0 compatibility commitments.

- **v0.1** — Basic closed loop: predict, evaluate, learn, save, restore.
- **v0.2** — Reliability and diagnostics: prediction reports, cold-start, baseline comparison.
- **v0.3** — Sparse features and high-dimensional data: FeatureHasher, FTRL, Naive Bayes.
- **v0.4** — Drift detection: Page-Hinkley, ADWIN, KSWIN, adaptive learning.
- **v0.5** — Online decision-making: multi-armed bandits, contextual bandits.
- **v0.6** — Platform and ecosystem: WASM, Python bindings, Tokio Stream adapters.
- **v0.7** — Pluggable WASM handlers: signed `.rillhandler` packs, Wasmtime sandbox, IPC v2.
- **v0.13.0** — Last 0.x stable release.
- **v1.0.0-rc.1** — Start of the 1.0 candidate cycle: API, state format, IPC, WIT, runtime, and release channels were frozen.
- **v1.0.0** — First stable 1.x release; `local-ai-stable` advances only after the immutable public assets pass the independent host smoke.
- **v1.1.0** — Interpretable online decision-making: delayed feedback, feature identity, drift consensus, weighted learning, Preview Runtime v3 / Handler v2.
- **v1.2.0** — Release admission and full-platform post-verification: admission gate, native RISC-V/LoongArch/FreeBSD/Windows verification, index schema v3 with `targetLibc`.
- **v1.3.0** — Product-surface drift gates, Stable/Preview version convergence, TrustMetadata v1 key lifecycle, offline/released conformance, real fuzz harnesses, CycloneDX/SPDX SBOMs, and FTRL resource diagnostics.

The current 1.x line does not implement full deep learning; the future direction is "frozen neural encoder + RillML online adaptive head" (e.g., DL embedding → LinearRegression / LogisticRegression / LinUCB / Bandit → online adaptation), with an `inference-provider` abstraction reserved in the architecture. RillML is not intended to become a PyTorch/tinygrad replacement.

## 14. Naming

The project is officially named **RillML**.

**Rill** is a short display and conversational name used where the context is unambiguous. The project does not claim the bare `rill` package, module, or CLI namespace. Existing technical names such as `rill-ml`, `rill-runtime`, and `rill_ml` remain intentionally explicit. See [`docs/NAMING.md`](docs/NAMING.md).

## Correctness and validation

RillML is validated through multiple layers:

- Unit, integration, and doctests cover core math, serialization round-trips, and boundary behaviour; current counts are visible in `cargo test --workspace` output and the CI summary.
- Serialization round-trip tests for all stateful types.
- `proptest` property-based tests with fixed seeds (`rand_chacha`).
- Clippy with `-D warnings` in CI; rustfmt enforced.
- All examples are actually run and verified.

**Numerical stability:** Welford's algorithm for variance; numerically stable sigmoid; epsilon-guarded scaling; no panics in public APIs, all errors returned as `Result<_, RillError>`.

## License

Licensed under the MIT License ([LICENSE-MIT](LICENSE-MIT)).

## Contributing

Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a pull request. RillML follows a "real-need-driven" development principle: every new feature should solve a real problem in a real Rust application.