Skip to main content

Module stratify

Module stratify 

Source
Expand description

stratify_branch — substrate operator for classifier-routing.

Substrate counterpart of TS extra/composition/stratify.ts (D199, Unit 5 Q9.2 of SESSION-rust-port-layer-boundary.md). The TS stratify(name, source, rules, opts) -> Graph factory composes N instances of this branch operator (one per rule) inside a single Graph; the Graph wrapper itself stays binding-side (presentation under D193). The classifier-routing logic — two-input subscribe, reactive-rules cache, two-dep DIRTY gating, per-fire dispatch — is the Rust substrate.

§Semantics (mirrors TS _addBranch in stratify.ts)

  • Subscribes to BOTH source and rules. Rules first, then source — so push-on-subscribe of rules’ cached DATA arrives before any source DATA the branch processes (R2.2.7).
  • Two-dep DIRTY gating (TS parity). On either dep’s DIRTY, the handler buffers and waits. When BOTH deps have settled in the same wave (no pending DIRTY on either), the cached source value is classified under the cached rules. This eliminates the stale-rules race when both deps update inside a single core.batch().
  • rules DATA: replaces the cached rules handle. Retains the new handle; releases the previously cached one. No downstream emit (“future items only” — rules updates affect FUTURE source items classified under them, not the current one).
  • source DATA: buffered (with retain) until both deps settle. On resolve, invokes binding.invoke_stratify_classifier_fn(classifier_fn_id, rules_handle, value_handle). If true, the buffered handle’s retain transfers to the emit queue. If false, the handle is released. If no rules handle has arrived (sentinel state), the buffered source DATA is dropped — matches TS “rule not found → false”.
  • source COMPLETE / ERROR / TEARDOWN: forwarded unchanged. F1 fix (QA 2026-05-14) — TEARDOWN forwarding restored to match TS if (depIndex === 0) actions.down([msg]) for tier 5 + 6.
  • rules COMPLETE / ERROR / TEARDOWN / INVALIDATE: silently absorbed. The branch keeps its last-seen rules cache and continues; rules’ terminals don’t propagate downstream of the branch (TS parity). F5 fix (QA 2026-05-14) — rules INVALIDATE intentionally does NOT clear latest_rules; matches TS, where rules’ INVALIDATE message is silently absorbed and latestRules keeps its previous value.
  • On producer deactivation: the Drop impl on StratifyState releases both the cached rules handle and any buffered source value via Weak<dyn BindingBoundary> (leaf-op safe).
  • N2 fix (QA 2026-05-14) — under Phase H+ STRICT scheduling, subscribe_to(rules, ...) may return Deferred, in which case the post-subscribe sync push doesn’t populate latest_rules before the source’s first DATA arrives. The build closure defensively reads core.cache_of(rules) and pre-seeds the cache when the sync push didn’t. Matches the TS factory-time latestRules = rulesNode.cache seeding.

Functions§

stratify_branch
Single classifier-routing branch. Each rule in a TS stratify(...) -> Graph becomes one instance of this operator.