docs← Back to article

Markdown for LLMs

Duty from entering a state

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# Duty from entering a state

## Intention

I want to count the duty window from an event of entering a state.

## Incorrect form and why it stays silent

```text title="Incorrect form"
// initial_state(p) считают событием-носителем с известным временем.
```

An initial state has no entry event. Until the instance carrier there is no Reply; binder e belongs to activation, not to the rule body.

## Correct form

```law
language "law.core" version "0.2";
package recipes.a.r10 version "0.1.0";
namespace "urn:recipe:a-positions:10";

entity Person;
relation registered(p: Person);
relation done(p: Person);
event Entered { }
relation entered_state(p: Person, e: Entered);
relation initial_state(p: Person);
rule R strict { for p: Person; for e: Entered; when registered(p);
    then duty Reply { bearer p; activation entered_state(p, e);
        achieve done(p) during [e.time.start, @2026-09-10T09:00:00+05:00]; };
}
```

## Frozen execution scene

| Facts and snapshot | Question | Answer |
|---|---|---|
| initial state only; 2026-09-05T09:00:00+05:00 | `positions()` | `not positions_present();` / `COMPUTED` |
| entry carrier; 2026-09-05T09:00:00+05:00 | `positions()` | `position_count(Reply, ACTIVE, 1);` / `COMPUTED` |

```law
test "initial state creates no position" {
    given {
        context {
            legal_time @2026-09-05T09:00:00+05:00;
            decision_time @2026-09-05T09:00:00+05:00;
            knowledge_time @2026-09-30T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert registered(entity_ref("urn:recipe:a-positions:10:p")); assert initial_state(entity_ref("urn:recipe:a-positions:10:p"));
    }
    evaluate positions();
    expect not positions_present();
    expect evaluation_status == COMPUTED;

}
```

```law
test "entry carrier activates duty" {
    given {
        context {
            legal_time @2026-09-05T09:00:00+05:00;
            decision_time @2026-09-05T09:00:00+05:00;
            knowledge_time @2026-09-30T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert registered(entity_ref("urn:recipe:a-positions:10:p")); assert entered_state(entity_ref("urn:recipe:a-positions:10:p"), Entered { id: "entry-1", time: @2026-09-02T09:00:00+05:00 });
    }
    evaluate positions();
    expect position_count(Reply, ACTIVE, 1);
    expect evaluation_status == COMPUTED;

}
```

Extra scene: with declaration `event Entered { actor: Person; }` and an actor field in the record the normative expectation is executed — e.time.start reads through the record with entity_ref, and the Reply position is created ACTIVE. The minimal scene above uses an event without an extra field; the person is bound by the entered_state relation.

```law
test "actor field carrier creates position" {
    given {
        context {
            legal_time @2026-09-05T09:00:00+05:00;
            decision_time @2026-09-05T09:00:00+05:00;
            knowledge_time @2026-09-30T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert registered(entity_ref("urn:recipe:a-positions:10:p")); assert entered_state(entity_ref("urn:recipe:a-positions:10:p"), Entered { id: "entry-1", time: @2026-09-02T09:00:00+05:00, actor: entity_ref("urn:recipe:a-positions:10:p") });
    }
    evaluate positions();
    expect position_count(Reply, ACTIVE, 1);
    expect evaluation_status == COMPUTED;

}
```

```python
>>> import runpy
>>> check = runpy.run_path("docs/recipes/a-positions/resources/check.py")
>>> check["check_event_record"]()
'А10: носитель с полем actor создаёт позицию; lawc = lawref'
```

## Counterfactual

Mutation: `activation entered_state(p, e);` → `activation entered_state(p, e) and entered_state(p, other);`; rejection LDC-E1330. Additional counterfactuals are shown as separate scenes.

## Boundary

entered_state here is an explicit profile entry, not a procedure implementation. Folding of transitions is covered by [Check event type and transition conditions](/recipes/k-procedures/event-conditions/); the carrier time follows the event canon.