Rikkola opened a new pull request, #7116:
URL: https://github.com/apache/incubator-kie/pull/7116

   ## Problem
   
   A rule guarded by `exists(A() and not B())` silently stops firing when a 
rule in a **different package** also uses `exists(A() and ...)`. No build 
error, no warning — the rule is simply never activated.
   
   Reproducer (four packages):
   
   ```drl
   // repro.a
   rule "produce-shared-fact" when Seed() then insert(new SharedFact()); end
   
   // repro.b  ← stops firing
   rule "subject" when exists(SharedFact() and not NegatedFact()) then 
insert(new Result()); end
   
   // repro.c  ← its presence breaks the rule above
   rule "sibling" when exists(SharedFact() and OtherFact()) then end
   ```
   
   `NegatedFact` and `OtherFact` are never inserted, so `subject` must fire. It 
does on 9.44.0.Final. It does not on 10.0–10.2 and current main.
   
   Related: apache/incubator-kie#7109
   
   ## Root cause
   
   Two commits combine to produce this bug:
   
   1. **[DROOLS-7238] Rete Buildtime Segmentation** (9b650b1) — introduced 
`SegmentPrototype.splitEagerProtos` with the guard:
      ```java
      if (proto1WasEager) { // if it wasn't eager before, nothing can be eager 
after
      ```
   2. **Split Beta Nodes** (2aa4b18) — introduced `ExistsRight`/`NotRight` 
wrapper nodes, enabling cross-subnetwork `JoinNode` sharing.
   
   Packages build sequentially. When `repro.b` is added, its inner segment 
contains both `JoinNode(SharedFact)` and `NotNode`. The joint presence of both 
suppresses the eager requirement (`requiresAnEagerSegment() = false`), so the 
segment is **not marked eager**. When `repro.c` is added later, `processSplit` 
splits the shared segment:
   
   - proto1 = `[JoinNode(SharedFact)]` — **not eager** (`proto1WasEager = 
false`)
   - proto2 = `[NotNode, TTON_subject]` — **eager** (NotNode without its 
JoinNode)
   
   `splitEagerProtos(proto1WasEager=false, proto2, TTON_subject)` hits the 
guard and exits immediately, so **proto2 is never registered** in 
`TTON_subject.eagerSegmentPrototypes`. At session creation, 
`initializePathMemory` finds an empty eager list → the `[NotNode, 
TTON_subject]` segment is never created → the NotNode's "start linked" state is 
never propagated → `ExistsNode_subject` is permanently unlinked → the outer 
rule never fires.
   
   ## Fix
   
   Add an `else if` branch in `splitEagerProtos` for the case where `proto1` 
was not eager but `other` (proto2) requires eager:
   
   ```java
   } else if (other.requiresEager()) {
       // proto1 was not eager, but the split produced an eager proto2.
       SegmentPrototype[] eager = endNode.getEagerSegmentPrototypes();
       SegmentPrototype[] newEager = new SegmentPrototype[eager.length + 1];
       System.arraycopy(eager, 0, newEager, 0, eager.length);
       newEager[newEager.length - 1] = other;
       endNode.setEagerSegmentPrototypes(newEager);
   }
   ```
   
   ## Test
   
   `ExistsWithNotSubnetworkCrossPackageTest` — 5 test methods × 2 configs 
(CLOUD_IDENTITY + CLOUD_EXEC_MODEL) = 10 parameterised instances:
   
   | Test | Purpose |
   |------|---------|
   | `subjectFiresWhenSiblingInDifferentPackage` | Direct regression: 
cross-package sibling, insert reproducer |
   | `subjectFiresWhenSiblingInDifferentPackageWithRuleChaining` | Rule-chained 
insert variant |
   | `subjectFiresWhenSiblingInSamePackage` | Same-package sibling must still 
fire (control) |
   | `subjectFiresWithoutSibling` | No sibling at all must still fire (control) 
|
   | `subjectFiresWithPlainJavaClasses` | Plain Java classes, not 
declare-type-specific |
   
   All 10 pass after fix. 310 tests across 9 regression suites all green 
(including the new `SegmentSplitAccumulateTest` from #7110).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to