# Distinguish a wrong carrier from other refusals ## Intent I want to explain why an attempt did not change the state, without mixing reasons. ## Wrong form and why it stays silent ```text title="Incorrect form" // Любая невалидная попытка якобы есть TRANSITION_CARRIER_TYPE_MISMATCH. ``` The code applies only to a mismatch with on Filed. Other reasons are read from procedure_step. Presentation to an entity without procedure_instance is a separate EVENT_OUTSIDE_PROCEDURE. ## Correct form ```law language "law.core" version "0.2"; package recipes.k.r07 version "0.1.0"; namespace "urn:recipe:k-procedures:07"; entity Application; event Filed { } event ElectronicFiled: Filed { } event Other { } relation ready(app: Application); relation approved(app: Application); procedure Filing(app: Application) { state Draft initial; state Done terminal; transition Submit { from Draft; to Done; on Filed; when ready(app); requires approved(app); } } ``` ## Frozen execution scene P and Q in the table are different instances; E1/E2/E3 are carriers with an explicitly given time. All identifiers and instants are pinned in the scenes. | Events and facts | Question | Answer | |---|---|---| | foreign carrier | `truth(current_state(P,Done))` | `truth_status == NEITHER;` / `COMPUTED` | | state preserved | `truth(current_state(P,Draft))` | `truth_status == TRUE_ONLY;` / `COMPUTED` | | false guard with the right type | `truth(current_state(P,Done))` | `truth_status == NEITHER;` / `COMPUTED` | | no instance | `truth(current_state(P,Done))` | `truth_status == NEITHER;` / `COMPUTED` | | on removed | `truth(current_state(P,Done))` | `truth_status == TRUE_ONLY;` / `COMPUTED` | | repeat from a left state | `why_not(valid_transition(P,Submit,Filed { id: "urn:recipe:k:N:E2", time: @2026-09-03T09:00:00Z }))` | `blocked_by("urn:recipe:k-procedures:07#Filing/Submit","from");` / `COMPUTED` | ```law test "foreign carrier leaves neither" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:07:p"));assert ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Other { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:07:p"),Done)); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; expect issue(TRANSITION_CARRIER_TYPE_MISMATCH); } ``` ```law test "draft state survives foreign carrier" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:07:p"));assert ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Other { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:07:p"),Draft)); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` ```law test "false guard blocks despite right type" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:07:p"));assert not ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Filed { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:07:p"),Done)); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; expect not issue(TRANSITION_CARRIER_TYPE_MISMATCH); } ``` ```law test "missing instance answers neither" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Filed { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:07:p"),Done)); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; expect issue(EVENT_OUTSIDE_PROCEDURE); } ``` ```law test "removed on admits other carrier" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:07:p"));assert ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Other { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:07:p"),Done)); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` ```law test "repeat from abandoned state names from" { given { context { legal_time @2026-09-13T09:00:00Z; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:07:p"));assert ready(entity_ref("urn:recipe:k-procedures:07:p")); assert approved(entity_ref("urn:recipe:k-procedures:07:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Filed { id: "urn:recipe:k-procedures:07:E1", time: @2026-09-02T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:07:p"), Submit, Filed { id: "urn:recipe:k-procedures:07:E2", time: @2026-09-03T09:00:00Z }); } evaluate why_not(valid_transition(entity_ref("urn:recipe:k-procedures:07:p"),Submit,Filed { id: "urn:recipe:k-procedures:07:E2", time: @2026-09-03T09:00:00Z })); expect blocked_by("urn:recipe:k-procedures:07#Filing/Submit","from"); expect evaluation_status == COMPUTED; } ``` ```python >>> import runpy >>> check = runpy.run_path("docs/recipes/k-procedures/resources/check.py") >>> check["check_steps"](https://github.com/arxohq/law/blob/master/docs/recipes/k-procedures/7) 'К7: причины шагов и отсутствие лишних предупреждений проверены; lawc = lawref' ``` ## Counterfactual Mutation check — LDC-E1344. Original fragment: ```text on Filed; ``` Replacement: ```text on ready; ``` Scenes with a condition removed are marked separately; the same inputs get a different outcome. ## Boundary A warning does not block computation; an order fatal from [Refuse when the order is undefined](/recipes/k-procedures/simultaneous-events/) does. A non-event in the carrier position is static E1347, and an unsuitable event type is a regular runtime outcome. A subtype is allowed — see [Check event type and transition conditions](/recipes/k-procedures/event-conditions/).