Skip to content

fix(flows): stop condition nodes starving downstream =item + dry-run routing-divergence warning (B15)#4698

Merged
graycyrus merged 1 commit into
tinyhumansai:mainfrom
graycyrus:fix/flows-condition-item-starvation
Jul 8, 2026
Merged

fix(flows): stop condition nodes starving downstream =item + dry-run routing-divergence warning (B15)#4698
graycyrus merged 1 commit into
tinyhumansai:mainfrom
graycyrus:fix/flows-condition-item-starvation

Conversation

@graycyrus

@graycyrus graycyrus commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Fixes B15 — a downstream node was silently starved after a condition, so an agent's input_context:"=item" resolved null → it hallucinated generic content ("@JDoe", not the real data). Proven on the "funny reminders" flow: every run generated a fake reminder. Two coupled tinyflows engine bugs + a dry-run blind spot.

Root cause (elegant — two bugs compound)

  • A1 (engine): a condition with only a true edge was lowered as an unconditional edge → the successor always ran, but collect_input port-matched true vs the emitted false and dropped the items → the successor ran with empty input. (Every existing condition test wires both edges, so this single-edge path was never covered.)
  • A2 (condition node): field was read as a literal key, so field:"=item.assignee" did get("=item.assignee") → always Nonealways false. Combined with A1 → always-false + always-runs-empty → =item null.

Fixes

  • tinyflows (via #5, pin bumped to 56d81df): a single non-main edge is now a conditional edge with an END fallback → a true-only condition acts as a filter (items flow on true, run ends on false); the condition node now resolves =-expressions in field.
  • openhuman dry-run: DryRunWorkflowTool now emits a routing-divergence warning when an agent/tool_call node never executed because a condition routed the mock data away — the exact class the dry-run missed (mock item shape ≠ real). Pure warning, doesn't flip ok.

Verification

tinyflows 304 lib + 12 doctests + --all-features e2e pass · openhuman cargo check clean · flows:: 392 pass (+ dry_run_warns_on_unexercised_agent_after_condition).

Summary by CodeRabbit

  • Bug Fixes

    • Dry-run checks now surface warnings when a workflow’s expected path does not match the path actually taken during validation.
    • Failure messages now include these routing warnings, making skipped steps easier to spot.
  • Tests

    • Added coverage for workflows where a branch is not exercised during dry-run validation and where it is exercised as expected.
  • Chores

    • Updated an internal dependency snapshot.

…dry-run routing divergence (B15)

A downstream agent's input_context "=item" resolved NULL after a `condition` node → the
agent hallucinated generic content ("@JDoe"), and the dry-run reported 0 warnings. Root
cause was two coupled engine bugs (fixed in tinyflows #5, pin bumped here) + a dry-run
blind spot (fixed here):

- tinyflows A1: a `true`-only condition was lowered as an unconditional edge; collect_input
  then dropped items on the emitted `false` port → successor ran with empty input. Now a
  single non-`main` edge is a conditional edge with an END fallback → the condition is a
  FILTER (items flow on true, run ends on false).
- tinyflows A2: the condition read `field` as a literal key, so `field:"=item.assignee"`
  never matched → always false. Now it resolves `=`-expressions and checks the resolved
  value's truthiness (literal fields unchanged).
- openhuman dry-run: DryRunWorkflowTool now emits a routing-divergence WARNING when an
  agent/tool_call node never executed because a condition routed the mock data away — the
  class the dry-run missed (mock item shape ≠ real). Pure warning, doesn't flip ok.

vendor/tinyflows pin -> 56d81df (tinyflows#5). tinyflows 304+12 tests pass; openhuman
cargo check clean; flows:: 392 pass (+ dry_run_warns_on_unexercised_agent_after_condition).
@graycyrus
graycyrus requested a review from a team July 8, 2026 10:00
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ffcfeb90-1756-4f81-b6f8-7cff59d9286c

📥 Commits

Reviewing files that changed from the base of the PR and between 0788443 and fb47a46.

📒 Files selected for processing (3)
  • src/openhuman/flows/builder_tools.rs
  • src/openhuman/flows/builder_tools_tests.rs
  • vendor/tinyflows

📝 Walkthrough

Walkthrough

DryRunWorkflowTool now detects "routing-divergence" cases where agent/tool_call nodes never execute because an upstream condition node takes a different branch under mock trigger input. A new find_upstream_condition helper attributes each unexecuted node to its nearest upstream condition, and results (both ok:true and ok:false) include a routing_divergence_warnings field with explanatory messages. Logging and tests were updated accordingly. The vendor/tinyflows submodule pointer was bumped.

Changes

Routing-Divergence Warning Feature

Layer / File(s) Summary
Routing-divergence detection logic
src/openhuman/flows/builder_tools.rs
Documents and implements detection of unexecuted agent/tool_call nodes via a new find_upstream_condition helper that walks predecessor edges to attribute unexecuted nodes to the nearest upstream condition, and logs a routing_divergence_warning_count.
Result JSON and messaging updates
src/openhuman/flows/builder_tools.rs
Adds routing_divergence_warnings to both ok: false and ok: true result JSON, extends the ok: false message and adds a note in the ok: true case explaining the warnings.
Tests for warning presence/absence
src/openhuman/flows/builder_tools_tests.rs
Adds two tests: one asserting a routing-divergence warning appears when a condition skips a downstream agent, another asserting an empty warnings array when the condition branch executes all downstream nodes.
Submodule pointer bump
vendor/tinyflows
Updates the tinyflows submodule to a new commit.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • tinyhumansai/openhuman#4586: Both PRs modify dry_run_workflow in builder_tools.rs and extend builder_tools_tests.rs with additional dry-run diagnostic assertions.
  • tinyhumansai/openhuman#4590: Both PRs extend dry_run_workflow diagnostics for agent-related execution issues in the same file.

Suggested labels: rust-core, bug

Poem

A condition forked, an agent slept,
No warning raised, no watch was kept.
Now I hop the graph, node by node,
Tracing branches down each road.
🐇 "Divergence found!" I thump with cheer —
unexecuted paths, at last made clear.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main changes: fixing condition-node routing issues and adding dry-run routing-divergence warnings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added bug rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Jul 8, 2026
@graycyrus
graycyrus merged commit 77786e5 into tinyhumansai:main Jul 8, 2026
18 of 22 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Team Openhuman Jul 8, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb47a46a22

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vendor/tinyflows
@@ -1 +1 @@
Subproject commit eb4865d1a16679b03fe79858c7b656adc34baa98
Subproject commit 56d81dfdadc1454189322d744e050ae4f7e525f9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve fan-in barriers for single conditional edges

When this bumps TinyFlows to 56d81df, its new single non-main edge lowering routes directly with add_conditional_edges before the existing fan-in check. In a graph where a true-only condition feeds a merge/fan-in that also has another independent predecessor, the merge can now be scheduled as soon as the condition branch fires instead of waiting for the other predecessor, so it observes partial input and produces an incomplete merge. The default-main path in the same TinyFlows change still applies incoming_counts/add_waiting_edge, so the new conditional path needs equivalent fan-in handling for the taken branch.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant