Skip to content

A rule may say or, once - #484

Merged
WaylandYang merged 4 commits into
devfrom
feat/a-rule-may-say-or
Sep 8, 2026
Merged

WaylandYang merged 4 commits into
devfrom
feat/a-rule-may-say-or

Conversation

@WaylandYang

Copy link
Copy Markdown
Contributor

Closes #476. Stacked on #483. Decision record: docs/decisions/0026-a-rule-may-say-or-once.md.

A criterion is rarely one pattern. A gas-bearing well is one whose total hydrocarbon is above 8 and whose interpretation reads as a gas anomaly — or one whose composite interpretation already says gas-bearing. Until now that was two rules, two names, the same conclusion, and nothing in the base saying they were one criterion: delete one and the other keeps firing.

The shape

A condition carries a group. Conditions in a group are joined with and; groups are joined with or. (A and B) or (C), one level, no nesting.

That is not a concession to keep the editor simple — it is the shape the evaluator already has. A hit does not report "true", it reports which facts made it true and the interval on which they all hold; getting there means walking the cartesian product of the per-condition matches and intersecting their intervals, which is a conjunction. Running that once per group keeps every property it has. An arbitrary and/or/not tree would have to answer "what are the premises of a disjunction", and neither answer is good: the fired branch's premises are what groups already give without the tree, and all of them would attach a conclusion to readings that had nothing to do with it.

What changed

  • Migration 0039 adds group_seq; existing conditions default to group 0, so every rule keeps its exact meaning. The unique key becomes (rule_id, group_seq, seq). (Numbered 39, not 38 — another branch owns 38 in the shared dev database.)
  • The evaluator runs group by group. The combination cap is per group: a group that blows past 64 is skipped and reported while the others still conclude, and the report counts a (rule, entity) pair once. Two groups true on the same interval are one conclusion, keeping the premises of the first group in group order so the proof is stable across runs.
  • not_in joins the ops. It reads a value that is there and asks whether it falls outside a set, so it has a premise and an interval like any other condition. "This entity has no such attribute at all" is deliberately not here — it has no premise, so nothing could ever retire it, and the base is open-world: a missing reading means nobody wrote it down.
  • The API carries group on a condition, defaulting to 0 — a caller that sends a flat list still sends one conjunction.
  • The editor writes blocks: rows joined by and at the head of the row, blocks divided by a rule and the word or, one button per block to add a row and one at the bottom to add a block. Deleting a block's last row takes the block with it, so no block is ever empty except the first one before anything is written — an empty conjunction is true of everything and there is no state in which one can be saved. Blocks are not boxed; the connectives already say how far a block reaches.
  • The table sentence reads A and B or C.

Tests

Four evaluator tests (either group fires and carries only its own premises; two groups on one interval are one hit; a capped group does not stop the other; not_in needs a reading to be true) and one database test that a rule with two groups names only the premises of the group that fired. Verified end to end against a running stack: a three-block rule written in the dialog stores 0,0,1,2 and reads back with both ors in the sentence.

Chaining — a rule reading what another rule concluded — is #477 and is not this.

🤖 Generated with Claude Code

@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch from 4e1b4b8 to c244bc3 Compare September 8, 2026 03:15
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 67c9f14 to 2aace5e Compare September 8, 2026 03:15
@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch from c244bc3 to 154ec34 Compare September 8, 2026 03:53
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 2aace5e to 2829f86 Compare September 8, 2026 03:53
@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch from 154ec34 to 38d1115 Compare September 8, 2026 04:10
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 2829f86 to 2613d6a Compare September 8, 2026 04:10
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 2613d6a to 5127dd4 Compare September 8, 2026 04:41
@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch from 38d1115 to 4671d37 Compare September 8, 2026 04:41
WaylandYang added a commit that referenced this pull request Sep 8, 2026
Three records were written as 0026-0028 on three branches on the same day. By the order the pull requests were opened, the adjudication stack (#473-#475) keeps 0026-0028, the rules stack (#484, #485) becomes 0029 and 0030, and the event record (#487) becomes 0031.

Signed-off-by: WaylandYang <wayland0916@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 5127dd4 to ea36c26 Compare September 8, 2026 05:03
@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch 2 times, most recently from 6c67fdb to ac19eca Compare September 8, 2026 05:08
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch 2 times, most recently from 8b9509a to 3219159 Compare September 8, 2026 05:12
@WaylandYang
WaylandYang force-pushed the feat/a-rule-is-an-edge branch 2 times, most recently from 4f2b54d to 769f376 Compare September 8, 2026 05:18
Base automatically changed from feat/a-rule-is-an-edge to dev September 8, 2026 05:21
WaylandYang and others added 4 commits September 8, 2026 13:21
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang
WaylandYang force-pushed the feat/a-rule-may-say-or branch from 3219159 to e78ec78 Compare September 8, 2026 05:21
@WaylandYang
WaylandYang merged commit cae4291 into dev Sep 8, 2026
4 checks passed
@WaylandYang
WaylandYang deleted the feat/a-rule-may-say-or branch September 8, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A rule can only say “and”

1 participant