# Distinguish repeal, suspension, and restoration ## Intent I want to keep the history of an edition’s force. ## Wrong form and why it stays silent Suspension is not a fifth operation over the text. An attempt at op suspend proceeds with warning LDC-E1302: the operation is skipped, it has no effect. That is not a successful suspension; the full counterfactual below removes precisely the lifecycle interval. ```law title="Incorrect form" relation suspends; effective @2026-03-01; op suspend { locator "article/1"; } ``` ## Correct form ```law language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; source Act { kind policy; } edition E of Act { language ru; officiality unofficial; materialization_status ABSTRACT_ONLY; in_force [@2026-01-01, infinity); suspended [@2026-03-01, @2026-04-01); restored @2026-04-01; repealed @2026-08-01; } edition Record of Act { language ru; officiality unofficial; materialization_status ABSTRACT_ONLY; in_force [@2026-01-01, infinity); } revision Pause { previous E; next Record; relation suspends; effective @2026-03-01; } fragment Copy in Record { kind article; locator "article/1"; text ru unofficial """Заявление принимается."""; } fragment F in E { kind article; locator "article/1"; text ru unofficial """Заявление принимается."""; } entity Person; relation filed(p: Person); relation accepted(p: Person); @source(F) rule Accept strict { for p: Person; when filed(p); then accepted(p); } ``` ## Frozen execution scene The scenes below present one filed on different dates: before the start — NEITHER, in force — TRUE_ONLY, during suspension — NEITHER, after restoration — TRUE_ONLY, after repeal — NEITHER. ```python >>> import runpy >>> checks = runpy.run_path("docs/recipes/i-sources/resources/check.py") >>> checks["lifecycle"](https://github.com/arxohq/law/blob/master/docs/recipes/i-sources/6) True ``` Scene 1; full program. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "before edition force gives neither" { given { context { legal_time @2025-12-31; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` Scene 2; full program. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "edition in force establishes" { given { context { legal_time @2026-02-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` Scene 3; full program. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "suspended edition gives neither" { given { context { legal_time @2026-03-15; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` Scene 4; full program. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "restored edition establishes" { given { context { legal_time @2026-04-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` Scene 5; full program. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "repealed edition gives neither" { given { context { legal_time @2026-08-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` Scene 6; `revision Pause { previous E; next Record; relation suspends; effective @2026-03-01; }` is removed. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "missing revision edge keeps suspension" { given { context { legal_time @2026-03-15; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` Scene 7; `suspended [@2026-03-01, @2026-04-01);` is removed. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "removed suspension interval restores truth" { given { context { legal_time @2026-03-15; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` Additional scene: replace `repealed @2026-08-01;` with `expired @2026-08-01;`. The answer is NEITHER, closure applies from the named date; the example does not imply retroactivity. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "expired close gives neither" { given { context { legal_time @2026-08-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` Additional scene: replace `repealed @2026-08-01;` with `invalidated @2026-08-01;`. The answer is NEITHER, closure applies from the named date; the example does not imply retroactivity. ```lawtest language "law.core" version "0.2"; package recipe.i06 version "1.0.0"; namespace "urn:recipe:i-sources:06"; test "invalidated close gives neither" { given { context { legal_time @2026-08-01; decision_time @2026-09-13T09:00:00Z; knowledge_time @2026-09-13T09:00:00Z; timezone "UTC"; } assert filed(entity_ref("urn:recipe:i-sources:person")); } evaluate truth(accepted(entity_ref("urn:recipe:i-sources:person"))); expect truth_status == NEITHER; expect evaluation_status == COMPUTED; } ``` ## Counterfactual The `teaches` mutation reproduces `LDC-E1302`. Additional variants are checked by the shown adapter call. ## Boundary A revision edge is provenance; applicability is read from lifecycle. A new restores edge is not a graph rollback. ## Pitfall Nodes under closed anchors are no longer executed. Here removal of lifecycle, unlike removal of the edge, changes the answer.