8000 fix: fit each nitrogen form, restore the ammonium allowance, replace the 1 % band by rafatahmed · Pull Request #213 · rafatahmed/Flahax · GitHub
[go: up one dir, main page]

Skip to content

fix: fit each nitrogen form, restore the ammonium allowance, replace the 1 % band - #213

Merged
rafatahmed merged 9 commits into
mainfrom
fix/nitrogen-total-and-ammonium
Oct 30, 2026
Merged

rafatahmed merged 9 commits into
mainfrom
fix/nitrogen-total-and-ammonium

Conversation

@rafatahmed
Copy link
Copy Markdown
Owner

Closes #209
Closes #210
Closes #211
Closes #212
Refs #201

Nitrogen forms, the ammonium allowance and the numerical tolerance (decisions D1, G23, G24 and G25 of 2026-10-29), plus sources described without "owner" wording.

Nitrogen (D1, G23, G24)

  • Separate targets: NO₃-N, NH₄-N and urea-N are each their own target. Total N is reported as their sum and is never a target.
  • Ammonium: NH₄-N absent or 0 sets no row and no ban. Incidental NH₄-N is capped at min(10 % of total N, 1.5 mmol/L = 21.01 mg/L), with basis "Dutch soilless practice (De Kreij, Voogt et al.)". The cap and total N are shown on the grower report and the batch and mix sheets.
  • Urea: urea-N not named in the formula is a declared zero. Urea-bearing products are excluded unless the formula names urea.
  • Consistency: total N is recalculated after the pH reagent. The same nitrogen rules apply in recommend, solve_weights, the joint problem and the pH refits.

Tolerance (G25)

  • Values: requirement_fit.met replaces the ±1 % band, with 1e-5 relative, 1e-6 mg/L for declared zeros and 1e-4 pH.
  • What blocks: only a broken declared maximum. A missed target is reported, and the stage becomes requires_review with "targets missed: …".
  • pH reagent stages: titration, acid selection and nitric judge only the change their own reagent causes. maximum_nutrient_error_percent has no default. A recipe the formulation stage accepted, including an empty one, never blocks a later stage.
  • Changed tests: every test that relied on the ±1 % band was changed to assert exact reported values; none was weakened. The full list, old → new, is in .superpowers/sdd/implementation-plan/task-3.2-report.md (local).

Wording (#211)

  • Removed: "owner" wording in code, tests, data notes and docs. The published release notes 0.3.0–0.6.0 are unchanged.
  • Renamed provenance values: owner_supplied_analysis → supplier_analysis, owner_supplied → supplier_supplied, owner_supplied_product_information → supplier_product_information.
  • Data files: only free-text notes and these values changed. No number, name, id or structure changed.
  • Tests: markers now read # Catalogue v0.0: re-enable in PR <n> (G<k>), and tests/test_owner_catalogue.py → tests/test_packaged_catalogue.py.

Left for PR 4

Tests still marked PR 4 (G5) wait for the potassium nitrate label gate to be removed. Several also fail on catalogue content: the packaged Tomato mixes at pH 4.76, and Tomato misses a target by 1.9 %. They will need rewrites in PR 4, not only re-enabling.

Verification

  • Full local suite: only the known local-only failures, from untracked .venv headers and untracked phreeqc.log inventory drift.
  • Style and distribution: ruff 0.8.4 check and format are clean, and tools/verify_distribution.py passes.
  • Reviews: each task was reviewed. Fix rounds were re-reviewed until approved.

N_NO3, N_NH4 and N_UREA are each their own fitted target (D1); total N
is reported in totalN as their sum and never fitted. An absent N_UREA is
a declared zero. N_NH4 absent or 0 sets no row and no ban (G24): calcium
nitrate stays eligible and incidental NH4-N is held within
min(10 % of total N, 1.5 mmol/L), Dutch soilless practice (De Kreij,
Voogt et al.), reported in ammoniumLimit and the batch summary (G23).
solve_weights, plan_coupled_ph and make_joint_problem use the same
nitrogen rows; the joint search holds the allowance as a maximum.

Generic explicit-zero tests use Na as their example ion; tests about the
ammonium rule assert the G23/G24 behaviour with exact values. Tests
marked G24 that pass on the packaged catalogue are re-enabled; the rest
carry the gate that now blocks them (G5 or G25). API_REFERENCE.md is
regenerated; the user guide, Python API, batch-command and
water-to-delivery pages describe the allowance.

Closes #209
Refs #201
…owance

A blended or joint pH-adjusted recipe kept the unadjusted totalN; total N
is now recomputed from the rebuilt rows (water, products and reagent)
through one helper, total_n_report. Blended recipes are assessed against
the same limits as their endpoints, including the ammonium allowance, so
incidental NH4-N no longer asks for review when it is within it.

solve_weights applies the same allowance as recommend (same
max_ammonium_fraction default, ammoniumLimit and totalN). The report,
batch sheet and mix sheet print the allowance with its basis, when it
applies, and total N as the reported sum of the forms, when nitrogen is
declared.

Refs #209
Refs #201
A target is met only within the numerical tolerance validated on
2026-10-24 (G25): 1e-5 relative, 1e-6 mg/L for a declared zero, 1e-4 pH.
The new module flahax.requirement_fit holds met() and the constants;
engine.TOLERANCE_PCT is removed and every use of it (feasible, the
short-target recovery, the target-only diagnosis and unmetTargets) now
uses met().

Only a broken declared maximum blocks the workflow (infeasible_recipe).
A missed target is a reported deviation: the formulation stage is
requires_review with "targets missed: ...", and the batch, titration,
acid and stock stages continue; FinalSolutionRecipe.feasible is true
unless the recommendation breaks a declared maximum. The batch and mix
sheets mark in red each target not met within the tolerance.

A target short by less than 1 % is now short, so recovery can admit its
only held-back source: on the packaged catalogue sodium molybdate meets
Mo for Lettuce 2 (Howard Resh). Tests that asserted the 1 %
band now assert met() or the reported deviation exactly.

Closes #210
Refs #201
The formulas-and-products page gains a nitrogen section (each form its
own target, total N reported and never fitted, absent urea a declared
zero, the ammonium allowance with its basis, Dutch soilless practice
(De Kreij, Voogt et al.)) and a section on when a target is met. The
Python API page, the user guide, the water-to-delivery and method pages
replace the 1 % band with the numerical tolerance. CHANGELOG and the
0.7.0 notes record both changes.

Refs #210
Refs #201
…in 1e-6

A deviation the formulation stage accepts no longer blocks a later stage.
The titration, nitric and acid-selection stages judge only the change
their reagent makes. maximum_nutrient_error_percent is optional with no
default (titration defaulted to 1 %); when given it is a declared
requirement on the reagent's own change to each positive target, from
the recipe before the reagent. A reagent that pushes a nutrient past a
declared maximum still blocks.

A declared zero is met within 1e-6 mg/L everywhere: assess_incidental,
the water-above-maximum conflict, the diagnosis and the sheets use met.
The pH plan and the joint workflow use requirement_fit.PH_TOLERANCE
(1e-4); the duplicate 1e-3 in ph_adjustment is removed.

Missed targets print with three significant figures in fixed notation
(+1400 %, not +1.4e+03). Docs, the user guide, the changelog and the
0.7.0 notes describe the rules.

Refs #210
Refs #201
…he target pH

The nitric adapter planned only a nonempty recipe, so an empty recipe the
formulation stage accepted (a zero maximum forbidding every product) still
blocked a later stage. It is now planned on the water alone, as acid
selection already did.

When the mixed pH is already within 1e-4 of the target, the pH stage no
longer says the feed needs a base: it says no pH reagent is needed, and
names why the plan without a reagent is not acceptable, if it is not.

maximum_nutrient_error_percent is checked the same way in the titration,
nitric and acid-selection stages (finite and positive, invalid_value); the
nitric adapter accepted 0. A pH band test pins the 1e-4 tolerance: 5e-4
from the mixed pH plans a converged acid or base, 5e-5 plans none.

Closes #212
Refs #210
owner_supplied_analysis, owner_supplied_product_information and
owner_supplied become supplier_analysis, supplier_product_information
and supplier_supplied in the packaged catalogue, the frozen 2026-10-29
audit catalogue and the catalogue workflow audit tool.
Name the catalogue (Flaha Agri Tech Analysis Ver 0.0), the 33c5df2
catalogue, the maintainer and the decision itself instead of "owner"
in code, comments, tests, docs and data notes. Rename the 33c5df2
fixture, tests/test_packaged_catalogue.py, RETIRED_TWO_TANKS and the
test identifiers; mark every 33c5df2 test "Catalogue v0.0: re-enable
in PR 4 (G5)". Update the identities and solubility hash pins and
regenerate API_REFERENCE.md. Published release notes 0.3.0-0.6.0 are
unchanged.

Closes #211
@rafatahmed rafatahmed added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Oct 30, 2026
@rafatahmed rafatahmed self-assigned this Oct 30, 2026
@read-the-docs-community
read-the-docs-community Bot commented Oct 30, 2026 •
Copy link
Copy Markdown

@codecov
codecov Bot commented Oct 30, 2026 •
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (984ea1b) to head (710173d).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #213   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          112       113    +1     
  Lines        13092     13191   +99     
  Branches      2605      2617   +12     
=========================================
+ Hits         13092     13191   +99     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rafatahmed
rafatahmed marked this pull request as ready for review October 30, 2026 23:53
@rafatahmed
rafatahmed merged commit 3eef252 into main Oct 30, 2026
13 checks passed
@rafatahmed
rafatahmed deleted the fix/nitrogen-total-and-ammonium branch October 30, 2026 23:53
rafatahmed added a commit that referenced this pull request Nov 7, 2026
fix: fit each nitrogen form, restore the ammonium allowance, replace the 1 % band
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

1 participant

0