Rules in memory
The memory is read by a one-pass decision engine, not a reasoner. Measured while building the demos and cookbooks with the English checkpoint, four things decide how a rule should be written.
1. Put conditions in code: rules with when
The engine does not compare numbers. With the line "Mia's stop-loss for a session is 30 units." in memory, the stop answer was 0.12 to 0.18 at a loss of 12 and still 0.22 to 0.30 at a loss of 30, where the limit is reached (measured 2026-09-23, cookbooks/rules_in_memory.py).
So Jers checks the condition in code and shows the engine the line only when it holds:
POST /v1/memory/rules
{"subject": "mia", "when": "session_result <= -30", "text": "Mia's stop-loss is reached: she stops playing now."}
POST /v1/systemone
{"subject": "mia", "values": {"session_result": -32}, "state": "...", "questions": {...}}
when is an expression over the request's values and the state's fields (reading.t > 75, days_since(order.date) > 30, contains(lower(message), "refund")), evaluated by an allow-listed evaluator: comparisons, and/or/not, arithmetic, and the functions days_since, days_between, len, lower, contains, number, abs, min, max, round. Nothing else runs. A fired rule's text is read like a memory line, placed before the recalled lines, and listed in memory.rules_fired; a rule whose expression fails is listed in rules_broken and the decision goes on. Rules may expire: send expires (an ISO date or time) or ttl_seconds (at most ten years), and the rule list shows expires_at. A when has at most 300 characters and a rule's text at most 500; a subject holds at most 100 rules. Rules are checked only when the decision uses the subject's memory, not with "memory": {"use": false}. GET /v1/memory/rules?subject= lists them and POST /v1/memory/rules/delete removes one. A rule is billed as one memory line written.
Measured through the gateway (measurements/jers-gateway-live-2026-09-23.txt, item 3): with the rule above, the stop answer was 0.11 at −10 (not fired) and 0.80 at −30 (fired). In the roulette demo the rule fired once, at −32, and the stop answer was 79%; before it fired the median stop answer was 13%.
2. Leave forbidden options out of the question
The engine does not read negation: naming the forbidden thing pulls it toward the answer. In the Dungeon demo, "Never walk along the corridor with the gold coins." raised the coins from 83% to 94%, and Jers warns when such a line is written.
A line that says what to do can help: in the Dungeon's Stone Hall the old bridge had 94% without memory, and with the line "Next time there, the hero goes along a dark muddy path" the muddy path had 70% and the hero took it (checked by the demo's test). It does not always help. On ten roulette states where 17 had just come up, the engine bet on 17 in 9 of 10 with no memory, 9 of 10 with a rule naming 17, and 10 of 10 with "Mia bets red, black, even, odd, low or high". What worked every time was offering only Mia's bets in the question: 0 of 10 (measured 2026-09-23, cookbooks/rules_in_memory.py).
So: when an option must never be chosen, remove it from criteria in your code. Use memory for what should make an allowed answer more likely.
3. Keep memories short
Lines can move an answer just by being there, in either direction: five neutral lines moved an escalation answer from 0.46 (no memory) to 0.28 (measurements/jers-recall-size-2026-09-23.json). Replace lines rather than append them, and check with "memory": {"placebo": true}: it reports questions that move with neutral lines as much as with yours.
4. Answers near a threshold are noisy
In the roulette demo, with the stop threshold at 50%, stray answers of up to 52% ended 2 of 9 sessions early (2026-09-23). For expensive actions require a fired rule, or two answers in a row above the threshold, and count early actions.
The pattern
- Facts as positive statements with the names your states use.
- Conditions as rules with
when, evaluated in code onvaluesand the state's fields. - Options that must never be chosen left out of the question in code; lines that say what to do, which may help but guarantee nothing.
compareandplaceboon while you develop, so every decision shows what the memory did.