# Read inapplicability separately from truth ## Intent I want to read inapplicability separately from truth. ## Wrong form and why it stays silent NOT_APPLICABLE is not part of truth_status. In why_not, applicability belongs to the candidate, not automatically to the root answer. ```text title="Incorrect form" expect truth_status == NOT_APPLICABLE; ``` ## Correct form ```law language "law.core" version "0.2"; package recipe.m09 version "1.0.0"; namespace "urn:recipe:m-queries:09"; entity Person; relation eligible(p: Person); relation accepted(p: Person); rule Accept strict { for p: Person; effective [@2026-09-01, @2026-10-01); when eligible(p); then accepted(p); } ``` ## Frozen execution scene | Input / variant | Question | Expectation | |---|---|---| | 1. outside the window | `truth(accepted(entity_ref("urn:recipe:m-queries:p")))` | `truth_status == NEITHER; evaluation_status == COMPUTED;` | | 2. explanation outside the window | `why_not(accepted(entity_ref("urn:recipe:m-queries:p")))` | `evaluation_status == COMPUTED; blocked_by(Accept);` | | 3. applicable, but the body refuted | `why_not(accepted(entity_ref("urn:recipe:m-queries:p")))` | `evaluation_status == COMPUTED; blocked_by(Accept);` | | 4. applicable and fired | `truth(accepted(entity_ref("urn:recipe:m-queries:p")))` | `truth_status == TRUE_ONLY; evaluation_status == COMPUTED;` | ```law test "outside window answers neither" { given { context { legal_time @2026-10-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert eligible(entity_ref("urn:recipe:m-queries:p")); } evaluate truth(accepted(entity_ref("urn:recipe:m-queries:p"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` ```law test "explanation outside window names rule" { given { context { legal_time @2026-10-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert eligible(entity_ref("urn:recipe:m-queries:p")); } evaluate why_not(accepted(entity_ref("urn:recipe:m-queries:p"))); expect evaluation_status == COMPUTED; expect blocked_by(Accept); } ``` ```law test "refuted body names rule" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert not eligible(entity_ref("urn:recipe:m-queries:p")); } evaluate why_not(accepted(entity_ref("urn:recipe:m-queries:p"))); expect evaluation_status == COMPUTED; expect blocked_by(Accept); } ``` ```law test "applicable rule fires" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert eligible(entity_ref("urn:recipe:m-queries:p")); } evaluate truth(accepted(entity_ref("urn:recipe:m-queries:p"))); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` In scene 2 the path `results[0].value.value.blockers[0].applicability` equals NOT_APPLICABLE, the conjunct list is empty: the rule is outside effective. In scene 3 applicability is APPLICABLE, but trigger is NOT_SATISFIED. Both questions return truthStatus NEITHER. The root GRAPH result has no applicabilityStatus field; a candidate field must not be attributed to it. Check of result fields and extra inputs: ```python >>> import runpy >>> checks = runpy.run_path("docs/recipes/m-queries/resources/check.py") >>> checks["applicability"](https://github.com/arxohq/law/blob/master/docs/recipes/m-queries/9) True ``` ## Counterfactual The sidecar mutation reproduces `LDC-E1319`. Counterfactual table variants are executed separately; input errors are not passed off as NEITHER. ## Boundary APPLICABLE and SATISFIED are different axes. Absence of a rule’s application does not create negative support for its head. ## Pitfall A closed anchor or window lifts application but does not refute the head — see [Move a rule onto the edition in force](/recipes/i-sources/closed-edition/).