Context
When a rule containing JoinNodes is removed via AuthoringSession.syncTo() → engine.apply(removed=[rule]), the JoinLeftBetaProcessor and JoinRightBetaProcessor are unsubscribed from the Router correctly, but per-unit JoinMemory entries for those join nodes are not cleared.
Impact
Stale tuples accumulate in NodeMemories for disposed join chains. No incorrect firings (processors are unsubscribed) but memory is not reclaimed until the unit is disposed.
Fix approach
On rule removal in ReteEngine.apply(), after unsubscribing root processors, walk the removed rule's processor chain and call a cleanup method on any MemoryFactory processors (JoinLeft/RightBetaProcessor) to clear per-unit memory entries.
Refs #6724
Context
When a rule containing JoinNodes is removed via AuthoringSession.syncTo() → engine.apply(removed=[rule]), the JoinLeftBetaProcessor and JoinRightBetaProcessor are unsubscribed from the Router correctly, but per-unit JoinMemory entries for those join nodes are not cleared.
Impact
Stale tuples accumulate in NodeMemories for disposed join chains. No incorrect firings (processors are unsubscribed) but memory is not reclaimed until the unit is disposed.
Fix approach
On rule removal in ReteEngine.apply(), after unsubscribing root processors, walk the removed rule's processor chain and call a cleanup method on any MemoryFactory processors (JoinLeft/RightBetaProcessor) to clear per-unit memory entries.
Refs #6724