Summary
Route-level sibling found while hoisting the chain admission predicates: the pandas/cuDF chain fast path declines prune_to_endpoints=True ("prune keeps only the arrival side → full path"), but the polars chain's plain single-hop branch admits the shape and returns both endpoints plus the edges, so polars and pandas disagree.
Repro
import pandas as pd, polars as pl, graphistry
from graphistry.compute.ast import n, e_forward
nodes = pd.DataFrame({"key": [1, 2, 3, 4, 5], "id": [10, 20, 30, 40, 50]})
edges = pd.DataFrame({"s": [1, 1, 2, 3, 3, 4], "d": [2, 3, 3, 1, 1, 5], "eid": range(6)})
ops = [n({"key": 1}), e_forward(prune_to_endpoints=True), n()]
graphistry.nodes(nodes, "key").edges(edges, "s", "d", "eid").gfql(ops) # nodes [2, 3], no edges
graphistry.nodes(pl.from_pandas(nodes), "key").edges(pl.from_pandas(edges), "s", "d", "eid").gfql(ops, engine="polars") # nodes [1, 2, 3], edges [0, 1]
Unseeded [n(), e_forward(prune_to_endpoints=True), n()]: pandas [1, 2, 3, 5], polars [1, 2, 3, 4, 5].
Expected
Either the polars plain branch declines prune_to_endpoints like the pandas gate (polars_plain_single_hop_admits is the single place to do it once the predicate refactor lands) or it implements the arrival-side contract; both engines must agree.
Pins
A strict-xfail parity pin lives in graphistry/tests/compute/gfql/lazy/engine/polars/test_chain_admission.py over the shared route corpus and flips when this is fixed.
Summary
Route-level sibling found while hoisting the chain admission predicates: the pandas/cuDF chain fast path declines
prune_to_endpoints=True("prune keeps only the arrival side → full path"), but the polars chain's plain single-hop branch admits the shape and returns both endpoints plus the edges, so polars and pandas disagree.Repro
Unseeded
[n(), e_forward(prune_to_endpoints=True), n()]: pandas[1, 2, 3, 5], polars[1, 2, 3, 4, 5].Expected
Either the polars plain branch declines
prune_to_endpointslike the pandas gate (polars_plain_single_hop_admitsis the single place to do it once the predicate refactor lands) or it implements the arrival-side contract; both engines must agree.Pins
A strict-xfail parity pin lives in
graphistry/tests/compute/gfql/lazy/engine/polars/test_chain_admission.pyover the shared route corpus and flips when this is fixed.