mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
* fix(agno): surface unevaluable policy rules (#778) * fix(agno): fixed qodo reviews check_policy previously let unevaluable policy rules silently return compliant=True with no signal (issue #778): a rule referencing a field missing from decision_data, or a rule string not matching the expected <field> <op> <value> format, both fell through _eval_rule's `return True` and were treated as passed. Both now raise ValueError, which routes through check_policy's existing exception handler and surfaces as a `warnings` entry instead. compliant/ violations semantics are unchanged for every case that previously worked correctly; an unevaluable rule is not counted as a violation since it's genuinely unknown whether it would have passed. Follow-up fixes from code review: - policy_rules decoded via json.loads without checking it was a list; a JSON-encoded bare string decoded to a Python str, so iterating it evaluated one "rule" per character, amplifying a single input-shape mistake into a wall of per-character warnings. A decoded string is now treated as a single rule; any other non-list shape or non-string list element produces exactly one warning instead. - _eval_rule used `data.get(field) is None` to detect a missing field, which can't distinguish an absent key from a key present with JSON null - both produced the same "undefined field" warning. Field presence is now checked with `field not in data` first, and a present-but-null value gets its own distinct message. Added regression tests for all of the above in tests/integrations/agno/test_decision_kit.py (38 tests in the file, 128 passing across tests/integrations/agno/). * fix(agno): reject non-object decision_data in check_policy check_policy only validated that decision_data was well-formed JSON, not that it decoded to an object. When it decoded to a list, `field not in data` in _eval_rule silently became list-membership testing of values instead of a dict key check - e.g. "confidence" not in ["confidence", 0.95] evaluates to False - so a matching rule fell through to data["confidence"], raising a raw internal TypeError ("list indices must be integers or slices, not str") instead of any meaningful diagnostic. Numbers, strings, and bools produced similarly opaque TypeErrors deep inside _eval_rule. check_policy now checks isinstance(data, dict) right after decoding and rejects any other shape with a single clear violations entry, the same way it already rejects malformed JSON. Added 5 regression tests in tests/integrations/agno/test_decision_kit.py covering list/number/string/bool/null decision_data shapes (43 tests in the file, 133 passing across tests/integrations/agno/). Addresses Copilot PR review comment on the #778 fix branch. * docs(changelog): reference PR #822 in the check_policy changelog entry --------- Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>