commit d148842002034f154f1c0e4f67a4860b92f442fc
parent 40206b4f63e4dd3f7def1267f2a677a3d1676a0d
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 13:01:22 +0000
core: add eligibility outcome types
Diffstat:
2 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/src/hyf_core/domain/eligibility.mojo b/src/hyf_core/domain/eligibility.mojo
@@ -0,0 +1,43 @@
+from std.collections import List
+
+
+@fieldwise_init
+struct ConstraintAssessment(Copyable, Movable):
+ var kind: String
+ var result: String
+ var mandatory: Bool
+ var reason: String
+
+
+def constraint_assessment(
+ kind: String, result: String, mandatory: Bool, reason: String
+) raises -> ConstraintAssessment:
+ if kind.strip() == "":
+ raise Error("constraint kind must not be empty")
+ if result != "pass" and result != "fail" and result != "unknown":
+ raise Error("constraint result must be 'pass', 'fail' or 'unknown'")
+ if reason.strip() == "":
+ raise Error("constraint reason must not be empty")
+ return ConstraintAssessment(
+ kind=String(kind),
+ result=String(result),
+ mandatory=mandatory,
+ reason=String(reason),
+ )
+
+
+def compose_eligibility(checks: List[ConstraintAssessment]) -> String:
+ var mandatory_fail = False
+ var mandatory_unknown = False
+ for check in checks:
+ if not check.mandatory:
+ continue
+ if check.result == "fail":
+ mandatory_fail = True
+ elif check.result == "unknown":
+ mandatory_unknown = True
+ if mandatory_fail:
+ return "ineligible"
+ if mandatory_unknown:
+ return "conditional"
+ return "eligible"
diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo
@@ -467,3 +467,29 @@ def test_supply_snapshot_revisions_and_unknown_unreserved() raises:
assert_true(snapshot_identity(known) != snapshot_identity(other_revision))
var unknown = supply_snapshot("lot-2", "l1", "farm-1", tomatoes, "unknown", 0, 0, "kg")
assert_true(not snapshot_unreserved_known(unknown))
+
+
+from hyf_core.domain.eligibility import (
+ ConstraintAssessment,
+ compose_eligibility,
+ constraint_assessment,
+)
+
+
+def test_eligibility_precedence() raises:
+ var checks = List[ConstraintAssessment]()
+ checks.append(constraint_assessment("product", "pass", True, "product_mismatch"))
+ checks.append(constraint_assessment("quantity", "unknown", True, "stock_unknown"))
+ checks.append(constraint_assessment("preference", "unknown", False, "evidence_insufficient"))
+ assert_equal(compose_eligibility(checks), "conditional")
+
+ var failing = List[ConstraintAssessment]()
+ failing.append(constraint_assessment("quantity", "fail", True, "quantity_insufficient"))
+ failing.append(constraint_assessment("window", "unknown", True, "window_mismatch"))
+ assert_equal(compose_eligibility(failing), "ineligible")
+
+ var optional_only = List[ConstraintAssessment]()
+ optional_only.append(constraint_assessment("preference", "unknown", False, "evidence_insufficient"))
+ assert_equal(compose_eligibility(optional_only), "eligible")
+ with assert_raises():
+ _ = constraint_assessment("product", "maybe", True, "x")