Skip to content

feat(gfql): fast-path engagement in gfql_explain + assert_fast_path - #1868

Merged
lmeyerov merged 3 commits into
masterfrom
feat/gfql-trace-fastpaths
Aug 11, 2026
Merged

feat(gfql): fast-path engagement in gfql_explain + assert_fast_path#1868
lmeyerov merged 3 commits into
masterfrom
feat/gfql-trace-fastpaths

Conversation

@lmeyerov

Copy link
Copy Markdown
Contributor

Extends the #1860 col-stats trace to the fast paths themselves — the surface the engagement audit needs.

Fast paths are contracted same answer, faster, so a dead one is invisible: the fallback returns the right result and every value test passes. Ratio in test_lowering.py: 665 value assertions vs 42 engagement.

Recorded at the call site, not via shims

gfql_unified imports these names directly, so patching the definition site never intercepts — that already produced one false negative during an audit here. Recording where the decision is consumed is one place, covers every return path, and cannot be bypassed.

Pins

  • both paths engage on their shapes
  • a shape neither serves declines both, answer still correct
  • short-circuit is distinguishable from decline — when grouped-agg serves, two_hop_count is absent rather than present-and-False; conflating them lets a genuinely dead path read as "declined for a good reason"
  • assert_fast_path fails when the path did not fire — an engagement pin that cannot fail is worse than none

Registered in POLARS_TEST_FILES; 0 non-cuDF failures locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi

@lmeyerov
lmeyerov force-pushed the feat/gfql-trace-fastpaths branch from 7f5890c to e707a87 Compare August 11, 2026 02:47
lmeyerov and others added 3 commits August 10, 2026 20:51
Extends the #1860 col-stats trace to the fast paths themselves, which is what
the engagement audit needs. Fast paths are contracted 'same answer, faster', so
a DEAD one is invisible: the fallback returns the right result and every value
test passes. Ratio in test_lowering.py: 665 value assertions vs 42 engagement.

Recorded at the CALL SITE in gfql_unified, not via shims or in-body hooks: it is
one place, it is where the decision is consumed, and it cannot be bypassed the
way patching a directly-imported name is -- gfql_unified imports these names
directly, which already produced one false negative during an audit.

assert_fast_path(g, query, path, served=) makes engagement a one-liner against a
PUBLIC surface. Pinned: both paths engage on their shapes; a shape neither serves
declines both with a correct answer; SHORT-CIRCUIT is distinguishable from
DECLINE (when grouped-agg serves, two_hop_count is absent from the map rather
than present-and-False -- conflating those lets a dead path read as 'declined for
a good reason'); and the helper FAILS when the path did not fire.

Registered in POLARS_TEST_FILES. Local: 0 non-cudf failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
Reviewer: insufficiently typed -- Any instead of Plottable, bare str instead of
Literal. All three flagged cases were real.

- FastPathName is now a Literal in index/types.py, next to the other index
  vocabularies. Closed BY CONSTRUCTION: adding a path means adding it there,
  which is what stops a typo silently recording a decision nobody can assert on.
- ColStatsOutcomeName likewise, and api.py's local copy now ALIASES it rather
  than duplicating the four strings in two files.
- g: Any -> Plottable, engine: str -> EngineAbstractType, and the outcomes map
  is keyed by the outcome Literal across all four engagement helpers -- including
  the two that landed in #1861 with the same weakness.
- The two remaining Any are on trace-step dicts, annotated hygiene-ok: a trace
  step is a heterogeneous TypedDict by contract, same rationale filter_mask_by_dict
  already carries.

Added a runtime pin for the Literal's failure mode: a mistyped path name must
fail LOUDLY, because 'never consulted' otherwise reads exactly like a correctly
declining path.

mypy clean on all changed modules; hygiene clean; lint 2/2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
Reviewer: cross-platform testing. Real gap -- the engagement pins were pandas-only,
and engagement is per-ENGINE: a fast path that serves on pandas can silently
DECLINE on polars or cuDF and no value test would notice, because both engines
still answer correctly via the fallback. That is the exact blind spot these pins
exist for, so pandas-only made them half a test.

All three shapes now run on all three engines (12 cases). Local: 11 pass, the one
cudf arm fails on this box's missing libnvrtc -- GPU-verified separately.

Note #1865 does NOT need the same treatment: _semi is a polars-only function and
polars does not mix eagerness, so eager/lazy IS its cross-platform axis, and
polars-gpu shares the CPU polars path. Already parametrized that way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
@lmeyerov
lmeyerov force-pushed the feat/gfql-trace-fastpaths branch from e7cbb3f to 13f9a21 Compare August 11, 2026 03:51
@lmeyerov
lmeyerov merged commit 88b95e4 into master Aug 11, 2026
77 checks passed
pull Bot pushed a commit to admariner/pygraphistry that referenced this pull request Aug 11, 2026
…agement

Closes the coverage gap the audit itself exposed: graphistry#1868 traced two of the three
fast paths, so a clean audit only meant 'the two instrumented ones fire'.
seeded_typed_hop is the third and last at this seam.

Its pin doubles as evidence about the other two: because it is consulted LAST,
seeing all three in one map proves the earlier paths DECLINED rather than
short-circuited.

The negative control caught this change, which is the point: it asserts an EXACT
dict, so adding a path forces it to be revisited. A control that silently ignores
a new path stops being a control -- the two failures on pandas and polars were
correct behaviour, not breakage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MF7uRZLKZaD6Q9FGWSmyXi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant