GFQL/Cypher: add validate-only gfql preflight API#1321
Merged
Conversation
21564bc to
e8d6510
Compare
d68ee48 to
8f6c593
Compare
This was referenced May 6, 2026
lmeyerov
added a commit
that referenced
this pull request
May 6, 2026
…QL lanes Per coordinator decision (2026-05-06): (1) Reframe `docs/source/gfql/strict_mode.rst` to lead with #1320/#1321's explicit preflight API (`g.gfql_validate(strict=True)`, `g.gfql(validate=True)`) as the primary operator entrypoint, and position the env-gate (`GRAPHISTRY_GFQL_STRICT_SCHEMA`) and catalog metadata as canary surfaces for the execution compile path's binder default. The two surfaces are independent: explicit preflight always runs strict regardless of env; env ladder governs only the non-validate-flagged execution path. (2) Fold the standalone `cypher-frontend-strict-rollout` job into the existing `test-gfql-core` and `test-pandas-compat-gfql` lanes — the rollout test files now run inside the matrix's main pytest invocation (default-loose path), and a follow-on `GRAPHISTRY_GFQL_STRICT_SCHEMA=true` step in the same job exercises the env-on canary path. No standalone lane needed. CHANGELOG entry updated to reflect both changes. Existing rollout module + tests + binder wiring unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 tasks
lmeyerov
added a commit
that referenced
this pull request
May 6, 2026
…1316) * T5 #1311: GFQL strict-schema rollout gate (env canary), CI receipt, operator docs Add a stable env-driven canary contract over the existing T2 binder strict-mode resolver, plus a focused CI receipt and an operator-guidance doc. Strictly additive — default loose mode behavior is unchanged. New module `graphistry/compute/gfql/rollout.py`: STRICT_SCHEMA_ENV = "GRAPHISTRY_GFQL_STRICT_SCHEMA" env_bool(name, default=False) strict_schema_env_default() resolve_strict_schema(*, explicit, catalog_strict) Re-exported from `graphistry.compute.gfql`. Wiring: `binder._strict_schema_mode` now delegates to the resolver, giving a monotonic precedence ladder — explicit param > catalog metadata > env > loose. Tests: 39 in test_rollout.py + 12 binder-integration tests pinning env-off preserves loose, env-on rejects unknown labels, explicit/catalog tiers still win, and valid queries continue to pass under env=strict. CI: new `cypher-frontend-strict-rollout` job runs the rollout slice twice — env-unset and env=true — gated on `cypher_frontend_ci`/`gfql` filters. Docs: new `docs/source/gfql/strict_mode.rst` (added to user-guide toctree) covers what strict mode is, three opt-in paths, precedence, diagnostic shape, and a recommended canary -> catalog -> param rollout sequence. Out of scope: Arrow-bridge gates (deferred until T4 #1312 contract surface exists). Meta-issue #1262 close criteria are not satisfied by this PR alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * review-w1: drop dead "" entry from ENV_FALSY env_bool short-circuits empty/whitespace before the falsy-set check, so the empty-string entry in ENV_FALSY was unreachable. Update test parametrize to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci-fix: annotate ENV_TRUTHY/ENV_FALSY with frozenset[str] cypher-frontend-strict-typing (mypy --strict --follow-imports=skip) flagged the bare `frozenset` annotations as missing type arguments. Add string-form annotations for forward compat across Python versions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci-fix: cast resolve_strict_schema return through bool() in binder cypher-frontend-strict-typing runs mypy with --follow-imports=skip, which treats imports from graphistry.compute.gfql.rollout as Any. This made the typed bool return from resolve_strict_schema look like Any to mypy and tripped --strict's no-any-return on _strict_schema_mode. Wrap the call in bool(...) so the function's declared bool return is satisfied without relying on the cross-module import being followed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * post-coordinator: docs reframe + fold strict-rollout into existing GFQL lanes Per coordinator decision (2026-05-06): (1) Reframe `docs/source/gfql/strict_mode.rst` to lead with #1320/#1321's explicit preflight API (`g.gfql_validate(strict=True)`, `g.gfql(validate=True)`) as the primary operator entrypoint, and position the env-gate (`GRAPHISTRY_GFQL_STRICT_SCHEMA`) and catalog metadata as canary surfaces for the execution compile path's binder default. The two surfaces are independent: explicit preflight always runs strict regardless of env; env ladder governs only the non-validate-flagged execution path. (2) Fold the standalone `cypher-frontend-strict-rollout` job into the existing `test-gfql-core` and `test-pandas-compat-gfql` lanes — the rollout test files now run inside the matrix's main pytest invocation (default-loose path), and a follow-on `GRAPHISTRY_GFQL_STRICT_SCHEMA=true` step in the same job exercises the env-on canary path. No standalone lane needed. CHANGELOG entry updated to reflect both changes. Existing rollout module + tests + binder wiring unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * strict_mode.rst: mark illustrative python blocks as doc-test:skip The repo's docs/test_doc_examples.py runs python code blocks against a synthetic graph fixture (`g`, `nodes`, `edges` with columns id/type/score etc). My code blocks reference Person/KNOWS labels and undefined symbols (`ast`, `ctx`) — they are operator-illustration snippets, not runnable against the fixture. Mark each python code block with `.. doc-test: skip` so the harness recognizes them as illustrative. Bash and text blocks auto-skip. Verified: pytest docs/test_doc_examples.py -k strict_mode -> 1 skipped (no failures); sibling cypher.rst / fundamentals.rst pass as before. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
g.gfql_validate(...)for GFQL and Cypher inputs without executiong.gfql(..., validate=True)andg.gfql_remote(..., validate=True)run preflight before local execution or remote upload/dispatchg.gfql_validate(...)to fail-fast exception semantics (raise on invalid queries) with structured inspectable payloads for LLM retry loopsAPI
ComputeMixin.gfql_validate(query, *, where=None, language=None, params=None, strict=False, collect_all=False) -> dictGFQLValidationError/GFQLSyntaxErrorfor invalid queriescollect_all=True, exception context includes fulldiagnosticsfor machine-readable repair workflowsBehavior
g.gfql_validate("...")treats string inputs as Cypher preflight by defaultg.gfql("...", validate=True)uses the same Cypher preflight path before executiong.gfql_remote(..., validate=True)validates locally before implicit upload/network execution when possibleTesting
PYTHONPATH=. python -m pytest -q graphistry/tests/compute/test_gfql_validate_only.pyPYTHONPATH=. python -m pytest -q graphistry/tests/compute/test_gfql.py -k "gfql_validate_true_runs_preflight_before_compile or gfql_validate_true_catches_cypher_schema_errors_by_default or gfql_validate_true_treats_all_strings_as_cypher"PYTHONPATH=. python -m pytest -q graphistry/tests/compute/test_chain_remote_v2.py -k "validate_true_rejects_before_implicit_upload or validate_true_uses_remote_safe_local_preflight"PYTHONPATH=. python -m pytest -q graphistry/tests/compute/test_chain_let.py -k "invalid_dag_type or chain_let_validates"PYTHONPATH=. python -m pytest -q docs/test_doc_examples.py -k "validation/fundamentals.rst or gfql/cypher.rst or validation/llm.rst"uv run ruff check graphistry/compute/gfql_validate.py graphistry/compute/gfql_unified.py graphistry/compute/chain_remote.py graphistry/tests/compute/test_gfql_validate_only.py graphistry/tests/compute/test_gfql.pyRefs #1320