Conversation
Renamed the NodeKind enum variants to use more descriptive names that better reflect their purpose in the model. This improves code readability and makes the intent of each variant clearer without changing any behavior. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The tests for node kind classification were asserting incorrect behavior, expecting certain node types to be classified in ways that did not match the actual implementation. This change updates the test assertions to reflect the correct classification logic, ensuring the tests validate the intended behavior rather than codifying the previous incorrect expectations. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The void node was previously simplified to a no-op, which broke control flow by allowing execution to continue past it. This change restores the original behavior where the void node halts execution, ensuring that downstream nodes are not reached. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The void tests were previously removed but are now restored to ensure that control flow nodes with void return types are properly tested. This re-adds the test cases that verify the expected behavior of void nodes in the control flow graph. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a trailing newline to the module file to comply with POSIX standards and avoid potential tooling warnings. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a trailing newline to the module file to comply with POSIX standards and avoid potential tooling warnings. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a trailing newline to the module file to comply with POSIX standards and avoid potential tooling warnings. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The execution loop previously skipped nodes whose state transition failed, leaving them permanently unexecuted. This change ensures that a failed transition does not prevent the node from being processed, restoring correct execution behavior. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the unused `std::collections::HashMap` import from the visualization module to keep the codebase clean and avoid compiler warnings. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test module was accidentally removed during a previous refactor, which caused the test suite to silently skip all node-related tests. This change restores the module so that the tests are executed again and regressions are caught. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test module was accidentally removed during a previous refactor, which caused the test suite to silently skip all node-related tests. This change restores the module so the tests are executed again. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The validator previously skipped validation when the input value was null, which allowed invalid null values to pass through unchecked. This change reintroduces the null check so that null inputs are properly rejected according to the validation rules. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The validator previously skipped a null check that was required to prevent a panic when processing certain input values. This change re-adds the check so that null values are handled gracefully instead of causing a runtime error. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The scatter validation previously skipped checks when the input collection was empty, allowing invalid scatter configurations to pass through unnoticed. This change re-enables validation for empty inputs so that scatter constraints are enforced consistently regardless of input size. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The scatter validation previously accepted an empty point list, which could lead to undefined behavior downstream when computing bounds or rendering. This change adds an explicit check that at least one point is present, returning a clear validation error instead. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The validator previously skipped a null check that was required to prevent a panic when processing certain input values. This change re-adds the check so that null values are handled gracefully instead of causing a runtime error. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The validator previously skipped a null check that was required to prevent a panic when processing certain input values. This change restores that check so validation behaves correctly and safely handles null inputs. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test file was previously truncated, removing several test cases that validated important edge cases in the validation logic. This change restores those tests to ensure the full suite of validation scenarios is covered again, preventing regressions in behavior that were previously guarded against. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test file was missing several assertions that verify validation behavior for edge cases. This change adds back the checks to ensure the validation logic is properly covered and prevents regressions. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds the contract definition for a new "void" node kind, which serves as an explicit terminal sink that accepts and discards items without running anything downstream. This makes intentional dead-ends distinguishable from accidentally unwired ports, and the contract documents its validation rules, output slot behavior, and interaction with scatter lanes and spawn nodes. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The catalog now includes the "void" node kind, extending the NODE_KINDS array to 21 entries and mapping it to its contract in contract_for. This makes the void node type available for use in the DSL alongside the existing node kinds. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The group_02 contract file was previously emptied, and this change restores its full set of type and trait definitions. This ensures the catalog contracts for this group are complete again, allowing dependent code to compile and function as expected. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The catalog now includes a new "void" node kind, so the test assertions for the total number of node kinds and contracts have been updated from 20 to 21, and the new kind is verified in the list. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add contract tests for the fan-out component to verify its behavior against the expected interface. This ensures the implementation adheres to the defined contract and catches regressions early. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The catalog test module was accidentally dropped during a refactor, leaving the catalog functionality without test coverage. This change restores the tests to ensure catalog behavior is verified and to prevent regressions. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added tests covering void node behavior, including parsing, rendering, and edge cases for empty and self-closing elements. This ensures void nodes are handled consistently across the codebase. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added tests covering void node behavior, including parsing, rendering, and edge cases for empty and self-closing elements. This ensures void nodes are handled consistently across the codebase. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a dedicated smoke test for the void node kind, which emits nothing by design and therefore cannot satisfy the non-empty slot assertion used by the generic single-node test. The new test verifies that a void node runs successfully, produces an empty items array, counts the discarded input, and leaves the port null. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds the `void` node to the catalog table, describing it as a terminal sink that discards input and runs nothing downstream, serving as an explicit dead end for pipelines. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
This change introduces a new wiki page documenting the available nodes, their purpose, and usage. It provides a reference for users to understand the catalog structure and node options. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The changelog entry describes the addition of a `void` node kind, a terminal sink that explicitly discards items on its `main` port and activates nothing. This provides a deliberate way to declare a branch as a side effect with no downstream consumer, distinguishing it from an accidentally unwired port. The entry also covers validation rules that reject `void` nodes with outgoing or missing incoming edges, the relaxation of the scatter-lane dead-end rule to allow lane branches ending in `void`, and the deliberate omission of a lint for `spawn` nodes without a `gate` or `void` downstream to preserve the documented fire-and-forget contract. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (22)
📝 WalkthroughWalkthroughChangesVoid terminal node
Estimated code review effort: 3 (Moderate) | ~25 minutes Mergeability Score: 🔵 Low · up to The PR adds an explicit sink that can discard routed errors or background-task tickets, so workflows may complete without surfacing failures from those side effects; owners should ensure mandatory audit, authorization, and notification work is independently tracked. Workflows persisted with the new Sequence Diagram(s)sequenceDiagram
participant WorkflowExecutor
participant VoidNode
participant NodeMetadata
WorkflowExecutor->>VoidNode: execute input items
VoidNode->>NodeMetadata: store discarded count
VoidNode-->>WorkflowExecutor: return empty output
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
Adds
NodeKind::Void(wire name"void") — a terminal sink. It accepts items onmain, discards them, and activates nothing. The branch ends there, on purpose.Why
A branch could always dead-end: a node with no outgoing edges is lowered to the state-graph's
ENDsentinel, which is filtered out of routing and contributes nothing to the next super-step's active set. Wiring nothing to a port has the same effect.What was missing is the statement. An unwired port reads exactly like a port someone forgot to wire, so an author could not declare "this branch is a side effect; nothing downstream waits on it", and a reviewer could not tell intent from an accident.
One place that ambiguity was resolved against the author: a branch inside a
scatterlane that dead-ends is a hard validation error, so fire-and-forget inside a lane was impossible to express at all.What it is not
voidstill runs inline in its own super-step; only the result is dropped. For work that should genuinely overlap, that isspawn+TaskRunner.spawnticket already does — which makesspawn → voidthe explicit spelling of "nogatewill ever collect this, and I meant that".Engine changes: none
engine.rs,graph/**andcompiler.rsare untouched. Leaf→ENDlowering plus theENDrouting filter already give the exact semantics. This is a model + executor + validation + catalog change.Validation rules
voidwith any outgoing edge is refused — it would be dead (a leaf lowers toEND) or would make the node not a void. The message names the offending targets, sorted for determinism.voidwith no incoming edge is refused. There is no general orphan check in the crate and adding one is out of scope, but a void-specific rule is safe (the kind is new, so no existing graph can trip it) and it is the one kind whose orphan is unambiguously meaningless: a node with no effect and no input.on_error: "route"on a void is caught directly, rather than lettingMissingErrorRoutefire. Anerroredge is an outgoing edge, so the author would otherwise be told to add an edge the next rule then rejects — advice with no fixed point.The scatter-lane relaxation
A lane branch ending in a
voidis now legal — this is the primary use case, and the one behavioural rule that had to change.The existing rule exists because a lane activation deliberately never writes the node's top-level slot, so an accidentally dead-ended lane node's output is invisible — a wrong answer rather than a failure. A
voidmakes that invisibility the contract instead of the accident. Side effects along the branch still happen once per lane; only the data is dropped.The hole stays closed.
region_membersreturns an empty set unless the walk reached a gather, and an emptymembersalready errors andcontinues — so ascatterwith nogatheranywhere is still refused, void downstream or not.a_scatter_whose_only_path_ends_in_void_is_still_rejectedpins exactly this. Separately, a void can never appear in a gather'sfromlist, since it cannot have an outgoing edge, so it cannot skew a release policy.Observability
The slot is
{items: [], port: null, discarded: N}. Emitting nothing would otherwise be indistinguishable from never having run, since a node that never ran has no slot at all:null)discarded: 0discarded: 3discardedcounts that activation, not a running total — in a loop body the last iteration's value survives, and in a scatter lane it lands underlanes.<lane>. A cumulative counter was considered and rejected: it would silently mean something different in each context.Deliberately not included
No lint for a
spawnwith neither agatenor avoiddownstream.validate_allreturnsVec<ValidationError>with no severity tier, so there is no warning channel, and making it a hard error would break the documented "fire-and-forget is legal" contract. Noted in the CHANGELOG as a possible future addition.Config
None. The node's existing
nameis where the human reason goes ("Fire and forget: audit log") — already required, and unlike a config key it is rendered byvisualization. Config is ignored entirely, including=expressions, so the node can emit no binding diagnostics.Tests
src/nodes/control_flow/void_tests.rs, 5): emits nothing / no port / no control; exactdiscardedcount; zero-input still reports0; ignores config and raises no diagnostics; pure across repeated activations.validate_tests_part_04, 10): leaf accepted; outgoing edge rejected; multiple targets named deterministically; no incoming edge rejected;on_error: "route"yields noMissingErrorRoute;stop/continueaccepted;executionstill rejected (pins void out of the mapping kinds); plus the three scatter-lane cases.tests/void_node_tests.rs, 6, all timeout-guarded since these failure modes hang rather than fail):fan_out_arm_into_void_does_not_block_the_other_arma_void_that_never_runs_leaves_no_slot_at_allvoid_arm_beside_a_merge_does_not_strand_the_barrierloop_body_with_a_void_side_branch_runs_every_iteration— the motivating casespawn_into_void_completes_without_a_gatescatter_lane_with_a_void_side_branch_gathers_all_lanessmoke_voidwith bespoke assertions —smoke_single_nodeasserts a non-emptyitemsslot, which a void can never satisfy.Verification
cargo fmt,cargo clippy --all-targets --all-features(clean),cargo test --all-features(39 test binaries, 0 failures),cargo checkon default /host-caps/store, andcargo publish --dry-run.Summary by CodeRabbit
voidnode that intentionally discards incoming items without triggering downstream execution.voidnodes have incoming connections and no outgoing connections.voidbehavior and examples.