Return the case and create a new duty
Intent
Section titled “Intent”I want, after a return to consideration, to open a new instance of a duty.
Wrong form and why it stays silent
Section titled “Wrong form and why it stays silent”state Decided terminal; // затем transition Return from DecidedA state with a lawful reverse transition is not terminal. A repeated entered_state carries a different event and creates a second Report position, keeping the first.
Correct form
Section titled “Correct form”language "law.core" version "0.2";package recipes.k.r03 version "0.1.0";namespace "urn:recipe:k-procedures:03";
entity Application;event Tick { }relation report(app: Application);procedure Appeal(app: Application) { state Draft initial; state Review; state Decided; state Closed terminal; transition Submit { from Draft; to Review; on Tick; } transition Decide { from Review; to Decided; on Tick; } transition Return { from Decided; to Review; on Tick; } transition Close { from Decided; to Closed; on Tick; }}rule Reporting strict { for app: Application; for e: Tick; when procedure_instance(app); then duty Report { bearer app; activation entered_state(app,Review,e); achieve report(app) during [e.time.start, @2026-09-20T09:00:00Z]; };}Frozen execution scene
Section titled “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 |
|---|---|---|
| initial state | positions() | not positions_present(); / COMPUTED |
| first entry | positions() | position_count(Report, ACTIVE, 1); / COMPUTED |
| return to consideration | positions() | position_count(Report, ACTIVE, 2); / COMPUTED |
| in consideration again | truth(current_state(P,Review)) | truth_status == TRUE_ONLY; / COMPUTED |
| first entry remains | truth(entered_state(P,Review,Tick { id: "urn:recipe:k:N:E1", time: @2026-09-02T09:00:00Z })) | truth_status == TRUE_ONLY; / COMPUTED |
| after the shared bound | positions() | position_count(Report, UNDETERMINED, 2); / COMPUTED |
initial state holds no positions
test "initial state holds no positions" { 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:03:p")); } evaluate positions(); expect not positions_present(); expect evaluation_status == COMPUTED;
}first entry activates duty
test "first entry activates duty" { 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:03:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Submit, Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z }); } evaluate positions(); expect position_count(Report, ACTIVE, 1); expect evaluation_status == COMPUTED;
}return opens second duty
test "return opens second duty" { 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:03:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Submit, Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Decide, Tick { id: "urn:recipe:k-procedures:03:E2", time: @2026-09-03T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Return, Tick { id: "urn:recipe:k-procedures:03:E3", time: @2026-09-05T09:00:00Z }); } evaluate positions(); expect position_count(Report, ACTIVE, 2); expect evaluation_status == COMPUTED;
}review state holds after return
test "review state holds after return" { 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:03:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Submit, Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Decide, Tick { id: "urn:recipe:k-procedures:03:E2", time: @2026-09-03T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Return, Tick { id: "urn:recipe:k-procedures:03:E3", time: @2026-09-05T09:00:00Z }); } evaluate truth(current_state(entity_ref("urn:recipe:k-procedures:03:p"),Review)); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED;
}first entry event preserved
test "first entry event preserved" { 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:03:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Submit, Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Decide, Tick { id: "urn:recipe:k-procedures:03:E2", time: @2026-09-03T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Return, Tick { id: "urn:recipe:k-procedures:03:E3", time: @2026-09-05T09:00:00Z }); } evaluate truth(entered_state(entity_ref("urn:recipe:k-procedures:03:p"),Review,Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z })); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED;
}closed common window leaves undetermined
test "closed common window leaves undetermined" { given { context { legal_time @2026-09-21T09:00:00Z; decision_time @2026-09-21T09:00:00Z; knowledge_time @2026-09-21T09:00:00Z; timezone "UTC"; } assert procedure_instance(entity_ref("urn:recipe:k-procedures:03:p"));assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Submit, Tick { id: "urn:recipe:k-procedures:03:E1", time: @2026-09-02T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Decide, Tick { id: "urn:recipe:k-procedures:03:E2", time: @2026-09-03T09:00:00Z });assert attempted_transition(entity_ref("urn:recipe:k-procedures:03:p"), Return, Tick { id: "urn:recipe:k-procedures:03:E3", time: @2026-09-05T09:00:00Z }); } evaluate positions(); expect position_count(Report, UNDETERMINED, 2); expect evaluation_status == COMPUTED;
}>>> import runpy>>> check = runpy.run_path("docs/recipes/k-procedures/resources/check.py")>>> check["check_positions"](https://github.com/arxohq/law/blob/master/docs/recipes/k-procedures/3)'К3: две позиции с разными activationEvent; первая сохраняется; lawc = lawref'Counterfactual
Section titled “Counterfactual”Mutation check — LDC-E1313.
Original fragment:
state Decided;Replacement:
state Decided terminal;Scenes with a condition removed are marked separately; the same inputs get a different outcome.
Boundary
Section titled “Boundary”The example isolates the start of the window: the rule gives both positions a shared end instant of 20 September; a repeated entry does not extend it. A term of “N days from each entry” needs a separate expression of the term. Carrier Tick carries no extra entity_ref fields; the known bound of reading them is described in Duty from entering a state.
Position statuses are read on the decision date: the scene past the shared boundary names a decision moment past it, otherwise both positions would stay active.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.