Metadata-Version: 2.4
Name: water-chemistry-engine
Version: 0.4.0
Summary: Reusable water-chemistry engine for brewing, fermentation, and other validated uses.
Author: Greg Roe
License-Expression: MPL-2.0
License-File: LICENSE
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: ferm-units>=0.1.3,<2.0.0
Requires-Dist: scipy>=1.17,<1.18
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/GregRR/water-chemistry-engine
Project-URL: Repository, https://github.com/GregRR/water-chemistry-engine
Project-URL: Issues, https://github.com/GregRR/water-chemistry-engine/issues
Description-Content-Type: text/markdown

# Water Chemistry Engine

A reusable, scientifically grounded Python engine for characterizing, blending,
treating, comparing, and optimizing water for brewing, fermentation, and other
validated uses.

The engine is intentionally independent of web frameworks, databases, graphical
interfaces, and product-specific persistence. End-user applications consume this
package from separate projects.

## Project status

The **0.4 automatic-treatment-optimizer milestone is complete**. The engine can
resolve reported source-water chemistry, optimize or preserve supported source
blends, choose bounded practical mineral doses, calculate the resulting water,
compare it with target/reference criteria, and return auditable candidate plans,
contributions, instructions, diagnostics, and notices.

Python 3.11 is the project compatibility baseline, with CI coverage through
Python 3.14. Public APIs remain pre-1.0 and may evolve as real consumer
applications exercise the engine.

Version 0.3 establishes a supported package-root consumer facade covering both
the deterministic forward-result graph and the complete source-reporting and
provenance input graph. Its compatibility expectations are documented in
the [consumer API guide](https://github.com/GregRR/water-chemistry-engine/blob/v0.4.0/docs/CONSUMER_API.md).
Reported and target pH use FermUnits' semantic `PHValue`; calculated
working-water pH remains explicitly deferred until a validated reusable model
is ready.

Version 0.3.1 expands the supported FermUnits dependency range to include the
stable 1.x series while retaining the compatible 0.1.3 floor; the Engine
continues to import unit functionality only through FermUnits.

Version 0.4 implements the first bounded automatic treatment
optimizer. It supports fixed blends, proportional dilution with an explicitly
characterized diluent, and bounded source-volume selection; chooses whole
caller-declared material dose increments; returns structured forward-replayed
plans; offers an equally close fewest-products alternative when materially
different; and can return an independently solved no-dilution best-effort plan.
The optimizer contract remains pre-1.0 and may evolve under the documented
consumer API compatibility policy.

### Forward-calculator capabilities established in 0.2

- source-water and target/reference profile models;
- preservation of exact values, ranges, bounds, `ND`, reported statistics,
  reporting context, source-document metadata, and chlorine/chloramine data;
- explicit source-resolution policy, including opt-in exact-range midpoints;
- fixed multi-source blending with conservative unknown propagation;
- supported mineral-addition stoichiometry and deterministic treatment;
- source, blend, and final target/reference comparison;
- combined source/treatment ion-contribution reporting;
- structured preparation instructions;
- structured notices for assumptions, unresolved inputs, model limitations,
  and deferred target-pH calculation.

### Release path

- **0.3.1:** FermUnits 1.0 compatibility and release-workflow maintenance;
- **0.4:** automatic treatment optimization with practical candidate plans,
  explicit feasibility/deviation diagnostics, and the minimum exact-composition
  treatment-material semantics needed for safe recommendations;
- **0.5:** broader practical treatment materials, curated target/reference
  profiles, and richer comparison semantics;
- **0.6:** optimizer and public-contract hardening beyond the first useful
  strategy set;
- **0.7:** reusable working-water pH if a defensible model is ready;
- **0.8:** BeerJSON/FermentationJSON interchange, conformance work, and 1.0
  hardening.

AI-assisted document ingestion, accounts, persistence, browser UI, and native
application code belong to separate consumer applications rather than this
repository.

## Repository structure

    water-chemistry-engine/
    ├── src/
    │   └── water_chemistry_engine/
    ├── tests/
    ├── docs/
    ├── reference-data/
    ├── schemas/
    ├── scripts/
    └── test-vectors/

### `src/water_chemistry_engine`

The importable Python engine package, using the standard `src/` layout. It owns
scientific calculations, domain models, validation, warnings/notices,
optimization as it is added, and structured calculation results.

External applications such as web, automation, Mechani-Brew, and future native
clients can consume the engine while providing their own interfaces and
persistence.

## Installation

Water Chemistry Engine requires Python 3.11 or newer. Install the published
package with uv or pip:

```bash
uv add water-chemistry-engine==0.4.0
```

or:

```bash
python -m pip install water-chemistry-engine==0.4.0
```

Version 0.3 exposes a supported package-root facade. APIs remain pre-1.0 and may
evolve under the [consumer API compatibility policy](https://github.com/GregRR/water-chemistry-engine/blob/v0.4.0/docs/CONSUMER_API.md).

## Quickstart

This example resolves and blends equal volumes of two reported source waters.
Calcium therefore blends from 40 mg/L and 80 mg/L to 60 mg/L:

```python
from fermunits import Q_

from water_chemistry_engine import (
    ForwardWaterSource,
    Ion,
    IonConcentration,
    SourceResolutionPolicy,
    SourceWaterProfile,
    calculate_forward_water,
)

source_a = SourceWaterProfile(
    name="Source A",
    concentrations=(IonConcentration.mg_per_liter(Ion.CALCIUM, 40.0),),
)
source_b = SourceWaterProfile(
    name="Source B",
    concentrations=(IonConcentration.mg_per_liter(Ion.CALCIUM, 80.0),),
)

result = calculate_forward_water(
    (
        ForwardWaterSource(source_a, Q_(1.0, "liter")),
        ForwardWaterSource(source_b, Q_(1.0, "liter")),
    ),
    source_resolution_policy=SourceResolutionPolicy(allow_exact_range_midpoints=False),
)

calcium = result.final_state.concentration_for(Ion.CALCIUM)
assert calcium is not None
print(calcium)
```

Expected output:

```text
60.0 milligram / liter
```

The explicit source-resolution policy prevents the example from silently
choosing representative values for ranges. See the
[consumer API guide](https://github.com/GregRR/water-chemistry-engine/blob/v0.4.0/docs/CONSUMER_API.md)
for the complete supported workflow, including treatments, targets, notices,
and audit results.

## Development stack

- Python 3.11+ (CI tests 3.11–3.14; 3.11 is the compatibility baseline)
- uv
- FermUnits
- pytest and Hypothesis
- Ruff
- mypy
- GitHub Actions

## Development

Install uv, then run from the repository root. The checked-in
`.python-version` selects the Python 3.11 compatibility baseline:

```bash
uv sync --dev
uv run pytest
```

The full CI gate tests Python 3.11, 3.12, 3.13, and 3.14. It also checks the
lockfile, formatting, linting, strict typing against Python 3.11 semantics, and
builds the engine distribution.

## Documentation

Primary project documents are stored under `docs/`:

- `WATER_CHEM_DESIGN.md` — scientific and architectural design;
- `WATER_CHEM_REFERENCES.md` — source and reference register;
- `ROADMAP.md` — active engine release path;
- `PROJECT_STRUCTURE.md` — repository/package boundaries;
- `CONSUMER_API.md` — supported 0.4 package-root facade and integration guide;
- `reviews/` — point-in-time external review records.

Release history is summarized in `CHANGELOG.md`.

## License

This project is licensed under the Mozilla Public License 2.0.
