Metadata-Version: 2.4
Name: seine-rs
Version: 0.4.30
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Scientific/Engineering
Requires-Dist: pyarrow ; extra == 'arrow'
Requires-Dist: pandas>=2.0 ; extra == 'pandas'
Requires-Dist: pyarrow ; extra == 'pandas'
Requires-Dist: polars ; extra == 'polars'
Provides-Extra: arrow
Provides-Extra: pandas
Provides-Extra: polars
Summary: Differentially certified Drools-subset rule engine over Arrow dataframes
Keywords: rules-engine,drools,rete,phreak,arrow,polars,dataframe
Author-email: Bryan McGuire <bryan@silverlakeagentics.com>
License: Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Repository, https://github.com/sl-agentics/seine

# seine-rs

A rules/decisioning engine over Arrow dataframes — a Rust port of a
bounded Drools (DRL) subset, **differentially certified against real
Drools 9.44.0.Final**: every supported behavior is pinned by running
the same scenarios through both engines, plus multi-seed fuzz
campaigns (zero divergences to completion).

```python
import polars as pl
import seine_rs
from seine_rs import Rule, fact

@fact
class Person:
    name: str
    age: int
    score: float

@fact
class Flagged:
    name: str
    score: float

adults = Rule("Adults")
p = adults.when(Person, Person.age >= 18)
adults.then_insert(Flagged, name=p.name, score=p.score)

people = pl.DataFrame({"name": ["ada", "kurt"], "age": [36, 17], "score": [91.5, 99.0]})
res = seine_rs.run([adults], {Person: people, Flagged: []})

pl.DataFrame(res.derived["Flagged"])   # facts the rules created
pl.DataFrame(res.firings)              # full audit trail
```

- **Bulk, columnar boundary**: Arrow tables in (polars / pyarrow /
  pandas ≥ 2.2, zero-copy via the PyCapsule interface), Arrow tables
  out. Row-object lists (`@fact` instances, dicts, dataclasses,
  Pydantic models) work too.
- **Rules in Python or DRL**: the Python builder compiles to DRL text,
  so both paths run the identical certified engine. Anything outside
  the certified grammar is a definition-time `CompileError`.
- **Full working-memory lifecycle**: `insert → fire → update/delete by
  handle → fire`, each certified differentially.
- **No Python in the hot path**: conditions, aggregates and salience
  are native; callbacks are observers over immutable results.

Install: `pip install seine-rs` — the import is `import seine_rs`.

Source, scenario corpus, and the full decision log (D-001…D-048):
https://github.com/sl-agentics/seine

