You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/optimizations.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -155,6 +155,8 @@ Union-find over node identity merges components when nodes list dependencies at
155
155
-**Feedback effect perpetually dirty status (Phase 8.1/8.2, noted 2026-04-06 QA — documented, accepted):** The `__feedback_effect_<condition>` node forwards DIRTY via default dispatch but consumes DATA. The effect stays in "dirty" status between emissions. **By design** — the status is technically correct. Effects don't need to settle. These nodes now carry `meta._internal: True` and can be filtered from `describe()` output when undesired.
156
156
- **Reduction primitives cross-language parity (Phase 8.1, noted 2026-04-06, QA 2026-04-06, updated 8.2 2026-04-06):** Both TS and PY implement `stratify`, `funnel`, `feedback`, `budget_gate`/`budgetGate`, and `scorer` in `patterns/reduction`. All five follow the orchestration factory pattern (`_base_meta`, `_register_step`). Key alignment: (1) `stratify` buffers DIRTY until DATA arrives — on classifier miss, emits `[DIRTY, RESOLVED]` to preserve spec §1.3.1 (both). (2) `funnel` now uses `bridge()` from `core/bridge` for inter-stage wiring — graph-visible effect nodes (`__bridge_<from>→<stage>_input`) replace the old subscribe-based bridges. Visible in `describe()`, participates in two-phase push. (3) `feedback` counter node is source of truth (resettable via `graph.set()`); feedback wiring now uses a graph-registered effect node (`__feedback_effect_<condition>`) instead of raw subscribe. Counter name is `__feedback_<condition>` to support multiple loops per graph. (4) `budget_gate`/`budgetGate` force-flushes all buffered items on terminal regardless of budget; sends RESUME before terminal if paused; forwards constraint ERROR downstream, silences constraint COMPLETE, forwards unknown constraint types via default. (5) `scorer` coerces `None`/`undefined` to 0 before multiplication (no TypeError/NaN divergence). TS `ScoredItem` is a plain object; PY `ScoredItem` is a class with `__slots__` and `__eq__`. Meta keys: `reduction: True`, `reduction_type: "<name>"`. Both repos: 22 tests each.
157
157
158
+
- **`stratify` two-dep gating (Phase 8.1/9.0, noted roadmap, resolved 2026-04-06, QA 2026-04-06):** `stratify` `on_message` previously intercepted only source messages (dep 0) and let rules messages (dep 1) fall through to default bitmask handling. When both source and rules updated in the same `batch()`, source DATA was classified against stale rules (rules DATA hadn't drained yet), and a spurious second emission occurred from default settlement of dep 1. Fix: `on_message` now intercepts **all** messages from both deps, implementing manual two-dep gating (same diamond-resolution pattern as `budget_gate`). Classification deferred until all dirty deps settle. Rules-only changes produce no downstream emission ("future items only"). QA hardening: (1) PAUSE/RESUME/INVALIDATE from rules dep swallowed (internal impl detail, not leaked downstream). (2) `classify` exceptions caught and treated as non-match (branch not killed). (3) `complete_when_deps_complete=False` explicit (branch lifecycle driven by source terminal, not auto-complete from both deps). Both TS and PY.
159
+
158
160
-**Cleanup wrapper `{"cleanup": fn, "value"?: v}` (all phases, noted 2026-04-06, resolved 2026-04-06):** Node fn can now return `{"cleanup": callable, "value": v}` to explicitly separate cleanup from data. When returned: `cleanup` is registered; if `"value"` key is present, it's emitted as data. Plain callable returns remain cleanup for backward compat. Exported as `CleanupResult<T>` (TS) / documented dict pattern (PY). Resolves the documented limitation where returning a callable as data was silently consumed as cleanup.
0 commit comments