graphforge 0.3.9__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (739) hide show
  1. {graphforge-0.3.9 → graphforge-0.4.0}/.github/SECURITY.md +10 -32
  2. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/docs.yml +12 -10
  3. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/test.yml +1 -1
  4. {graphforge-0.3.9 → graphforge-0.4.0}/.gitignore +4 -0
  5. {graphforge-0.3.9 → graphforge-0.4.0}/CHANGELOG.md +28 -0
  6. {graphforge-0.3.9 → graphforge-0.4.0}/CLAUDE.md +110 -1
  7. {graphforge-0.3.9 → graphforge-0.4.0}/Makefile +13 -1
  8. {graphforge-0.3.9 → graphforge-0.4.0}/PKG-INFO +60 -14
  9. {graphforge-0.3.9 → graphforge-0.4.0}/README.md +49 -8
  10. graphforge-0.4.0/benchmarks/algorithms/bench_gds.py +91 -0
  11. graphforge-0.4.0/benchmarks/baseline.md +34 -0
  12. graphforge-0.4.0/docs/architecture/overview.md +517 -0
  13. {graphforge-0.3.9 → graphforge-0.4.0}/docs/architecture/storage.md +1 -1
  14. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/contributing.md +2 -2
  15. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/perf-baseline-findings-v0.3.9.md +1 -1
  16. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/requirements.md +45 -25
  17. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/v0.4-revised-plan.md +3 -0
  18. {graphforge-0.3.9 → graphforge-0.4.0}/docs/getting-started/installation.md +23 -2
  19. {graphforge-0.3.9 → graphforge-0.4.0}/docs/getting-started/tutorial.md +1 -1
  20. graphforge-0.4.0/docs/guide/analytics-integration.md +234 -0
  21. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/INCOMPLETE_FEATURES_ISSUES.md +1 -1
  22. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/api.md +21 -0
  23. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/column-naming-behavior.md +1 -1
  24. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-compatibility.md +13 -64
  25. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/scale-limits.md +1 -4
  26. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/phase-1-complete.md +1 -2
  27. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/phase-2-complete.md +1 -1
  28. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/roadmap.md +22 -33
  29. graphforge-0.4.0/docs/research/agent-grounding-v040.md +224 -0
  30. graphforge-0.4.0/docs/research/agent-grounding.md +719 -0
  31. graphforge-0.4.0/docs/research/gds-network-analysis.md +189 -0
  32. graphforge-0.4.0/docs/research/genealogy.md +227 -0
  33. graphforge-0.4.0/docs/research/kg-construction.md +731 -0
  34. graphforge-0.4.0/docs/research/llm-context-building.md +179 -0
  35. graphforge-0.4.0/docs/research/llm-workflows.md +794 -0
  36. graphforge-0.4.0/docs/research/network-analysis.md +796 -0
  37. graphforge-0.4.0/docs/research/search-entity-resolution.md +186 -0
  38. {graphforge-0.3.9 → graphforge-0.4.0}/docs/use-cases/agent-grounding.md +141 -48
  39. {graphforge-0.3.9 → graphforge-0.4.0}/docs/use-cases/agent-tool-recall.md +112 -64
  40. {graphforge-0.3.9 → graphforge-0.4.0}/docs/use-cases/knowledge-graph-construction.md +120 -7
  41. {graphforge-0.3.9 → graphforge-0.4.0}/docs/use-cases/llm-workflows.md +179 -61
  42. {graphforge-0.3.9 → graphforge-0.4.0}/docs/use-cases/network-analysis.md +144 -62
  43. {graphforge-0.3.9 → graphforge-0.4.0}/examples/05_migration_from_networkx.py +40 -24
  44. {graphforge-0.3.9 → graphforge-0.4.0}/mkdocs.yml +32 -5
  45. {graphforge-0.3.9 → graphforge-0.4.0}/pyproject.toml +27 -10
  46. graphforge-0.4.0/scripts/benchmark_neighbourhood.py +421 -0
  47. graphforge-0.4.0/scripts/benchmark_tool_registry.py +329 -0
  48. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/tck_perf_report.py +2 -2
  49. graphforge-0.4.0/scripts/validate_agent_snippets.py +1188 -0
  50. graphforge-0.4.0/scripts/validate_llm_snippets.py +916 -0
  51. graphforge-0.4.0/src/graphforge/__init__.py +12 -0
  52. graphforge-0.4.0/src/graphforge/_compat.py +14 -0
  53. graphforge-0.4.0/src/graphforge/algorithms/__init__.py +5 -0
  54. graphforge-0.4.0/src/graphforge/algorithms/_dispatch.py +74 -0
  55. graphforge-0.4.0/src/graphforge/algorithms/centrality.py +128 -0
  56. graphforge-0.4.0/src/graphforge/algorithms/community.py +73 -0
  57. graphforge-0.4.0/src/graphforge/algorithms/gds.py +287 -0
  58. graphforge-0.4.0/src/graphforge/algorithms/structural.py +56 -0
  59. graphforge-0.4.0/src/graphforge/api.py +1935 -0
  60. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/ast/expression.py +17 -0
  61. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/exporters/json_graph.py +7 -2
  62. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/executor/executor.py +76 -1
  63. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/optimizer.py +13 -2
  64. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/parser/cypher.lark +10 -1
  65. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/parser/parser.py +27 -0
  66. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/planner/planner.py +27 -3
  67. graphforge-0.4.0/src/graphforge/recipes/__init__.py +49 -0
  68. graphforge-0.4.0/src/graphforge/search/__init__.py +6 -0
  69. graphforge-0.4.0/src/graphforge/search/search.py +647 -0
  70. graphforge-0.4.0/src/graphforge/search/types.py +31 -0
  71. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/types/values.py +89 -0
  72. {graphforge-0.3.9 → graphforge-0.4.0}/tests/conftest.py +19 -15
  73. graphforge-0.4.0/tests/integration/conftest.py +34 -0
  74. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_distinct_clause.py +45 -0
  75. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_exists_is_empty.py +76 -0
  76. graphforge-0.4.0/tests/integration/test_shortest_path.py +45 -0
  77. graphforge-0.4.0/tests/integration/test_three_surfaces.py +135 -0
  78. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_with_clause.py +69 -0
  79. graphforge-0.4.0/tests/unit/algorithms/__init__.py +0 -0
  80. graphforge-0.4.0/tests/unit/algorithms/test_gds.py +315 -0
  81. graphforge-0.4.0/tests/unit/api/test_add_graph_documents.py +261 -0
  82. graphforge-0.4.0/tests/unit/api/test_analytics.py +489 -0
  83. graphforge-0.4.0/tests/unit/api/test_cache.py +220 -0
  84. graphforge-0.4.0/tests/unit/api/test_json_io.py +261 -0
  85. graphforge-0.4.0/tests/unit/api/test_merge_node.py +156 -0
  86. graphforge-0.4.0/tests/unit/api/test_schema_introspection.py +163 -0
  87. graphforge-0.4.0/tests/unit/api/test_set_node_properties.py +166 -0
  88. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_registry.py +21 -0
  89. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_unwind_limit_short_circuit.py +35 -1
  90. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_redundant_elimination.py +53 -1
  91. graphforge-0.4.0/tests/unit/parser/test_shortest_path_parser.py +63 -0
  92. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_syntax_error_validation.py +10 -0
  93. graphforge-0.4.0/tests/unit/procedures/__init__.py +0 -0
  94. graphforge-0.4.0/tests/unit/recipes/__init__.py +0 -0
  95. graphforge-0.4.0/tests/unit/recipes/test_neighbourhood.py +113 -0
  96. graphforge-0.4.0/tests/unit/search/__init__.py +0 -0
  97. graphforge-0.4.0/tests/unit/search/test_search.py +610 -0
  98. graphforge-0.4.0/tests/unit/types/test_unwrap.py +179 -0
  99. {graphforge-0.3.9 → graphforge-0.4.0}/uv.lock +439 -16
  100. graphforge-0.3.9/coverage.json +0 -1
  101. graphforge-0.3.9/docs/architecture/overview.md +0 -797
  102. graphforge-0.3.9/src/graphforge/__init__.py +0 -9
  103. graphforge-0.3.9/src/graphforge/api.py +0 -995
  104. graphforge-0.3.9/tests/integration/conftest.py +0 -13
  105. {graphforge-0.3.9 → graphforge-0.4.0}/.codecov.yml +0 -0
  106. {graphforge-0.3.9 → graphforge-0.4.0}/.coderabbit.yaml +0 -0
  107. {graphforge-0.3.9 → graphforge-0.4.0}/.editorconfig +0 -0
  108. {graphforge-0.3.9 → graphforge-0.4.0}/.github/CODEOWNERS +0 -0
  109. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  110. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  111. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  112. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  113. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  114. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  115. {graphforge-0.3.9 → graphforge-0.4.0}/.github/ISSUE_WORKFLOW.md +0 -0
  116. {graphforge-0.3.9 → graphforge-0.4.0}/.github/dependabot.yml +0 -0
  117. {graphforge-0.3.9 → graphforge-0.4.0}/.github/pull_request_template.md +0 -0
  118. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/README.md +0 -0
  119. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/changelog-check.yml +0 -0
  120. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/pr-labeler.yml +0 -0
  121. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/publish.yaml +0 -0
  122. {graphforge-0.3.9 → graphforge-0.4.0}/.github/workflows/release-tracking.yml +0 -0
  123. {graphforge-0.3.9 → graphforge-0.4.0}/.pre-commit-config.yaml +0 -0
  124. {graphforge-0.3.9 → graphforge-0.4.0}/CHANGELOG_v0.3.0.md +0 -0
  125. {graphforge-0.3.9 → graphforge-0.4.0}/CODE_OF_CONDUCT.md +0 -0
  126. {graphforge-0.3.9 → graphforge-0.4.0}/CONTRIBUTING.md +0 -0
  127. {graphforge-0.3.9 → graphforge-0.4.0}/IMPLEMENTATION_PLAN.md +0 -0
  128. {graphforge-0.3.9 → graphforge-0.4.0}/LICENSE +0 -0
  129. {graphforge-0.3.9 → graphforge-0.4.0}/RELEASING.md +0 -0
  130. {graphforge-0.3.9 → graphforge-0.4.0}/benchmarks/.gitkeep +0 -0
  131. {graphforge-0.3.9/tests/perf → graphforge-0.4.0/benchmarks/algorithms}/__init__.py +0 -0
  132. {graphforge-0.3.9 → graphforge-0.4.0}/docs/architecture/ast-and-planning.md +0 -0
  133. {graphforge-0.3.9 → graphforge-0.4.0}/docs/architecture/execution-model.md +0 -0
  134. {graphforge-0.3.9 → graphforge-0.4.0}/docs/architecture/storage-analysis.md +0 -0
  135. {graphforge-0.3.9 → graphforge-0.4.0}/docs/community/code-of-conduct.md +0 -0
  136. {graphforge-0.3.9 → graphforge-0.4.0}/docs/community/security.md +0 -0
  137. {graphforge-0.3.9 → graphforge-0.4.0}/docs/cypher-guide.md +0 -0
  138. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/cypher-script-loading.md +0 -0
  139. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/ldbc.md +0 -0
  140. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/neo4j-examples.md +0 -0
  141. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/networkrepository.md +0 -0
  142. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/overview.md +0 -0
  143. {graphforge-0.3.9 → graphforge-0.4.0}/docs/datasets/snap.md +0 -0
  144. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/QUICKSTART_V0.2.md +0 -0
  145. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/codecov-integration.md +0 -0
  146. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/documentation-update-summary.md +0 -0
  147. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/parser-performance-analysis.md +0 -0
  148. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/perf-v038-to-v039-delta.md +0 -0
  149. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/phase-1a-completion-report.md +0 -0
  150. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/release-process.md +0 -0
  151. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/release-strategy.md +0 -0
  152. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-01-31-cicd-infrastructure.md +0 -0
  153. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-01-31-documentation.md +0 -0
  154. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-01-31-regression-fix.md +0 -0
  155. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-01-31-with-clause.md +0 -0
  156. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-02-01-codecov-setup.md +0 -0
  157. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-2026-02-01-column-naming-investigation.md +0 -0
  158. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/session-summary.md +0 -0
  159. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/tck-session-2026-01-31-final.md +0 -0
  160. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/sessions/tck-session-2026-01-31.md +0 -0
  161. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/tck_baseline_analysis_v0.3.md +0 -0
  162. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/testing-setup-complete.md +0 -0
  163. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/testing.md +0 -0
  164. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/v0.2-plan-summary.md +0 -0
  165. {graphforge-0.3.9 → graphforge-0.4.0}/docs/development/workflow.md +0 -0
  166. {graphforge-0.3.9 → graphforge-0.4.0}/docs/getting-started/quickstart.md +0 -0
  167. {graphforge-0.3.9 → graphforge-0.4.0}/docs/guide/cypher-guide.md +0 -0
  168. {graphforge-0.3.9 → graphforge-0.4.0}/docs/guide/graph-construction.md +0 -0
  169. {graphforge-0.3.9 → graphforge-0.4.0}/docs/guide/overview.md +0 -0
  170. {graphforge-0.3.9 → graphforge-0.4.0}/docs/index.md +0 -0
  171. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/README.md +0 -0
  172. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/RELEASE_TRACKING.md +0 -0
  173. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/VALIDATION_REPORT.md +0 -0
  174. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/changelog.md +0 -0
  175. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-aggregation-functions.md +0 -0
  176. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-graph-queries.md +0 -0
  177. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-graph-schema.md +0 -0
  178. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-mapping/clause-to-tck.md +0 -0
  179. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-mapping/function-to-tck.md +0 -0
  180. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-order-by.md +0 -0
  181. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/feature-return-aliasing.md +0 -0
  182. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/implementation-status/clauses.md +0 -0
  183. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/implementation-status/functions.md +0 -0
  184. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/implementation-status/operators.md +0 -0
  185. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/implementation-status/patterns.md +0 -0
  186. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-compatibility-matrix.md +0 -0
  187. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-features/01-clauses.md +0 -0
  188. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-features/02-functions.md +0 -0
  189. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-features/03-operators.md +0 -0
  190. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-features/04-patterns.md +0 -0
  191. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/opencypher-features/05-data-types.md +0 -0
  192. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/tck-compliance.md +0 -0
  193. {graphforge-0.3.9 → graphforge-0.4.0}/docs/reference/tck-inventory.md +0 -0
  194. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/implementation-summary.md +0 -0
  195. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/next-steps.md +0 -0
  196. {graphforge-0.3.9 → graphforge-0.4.0}/docs/releases/phase-3-complete.md +0 -0
  197. {graphforge-0.3.9 → graphforge-0.4.0}/docs/stylesheets/extra.css +0 -0
  198. {graphforge-0.3.9 → graphforge-0.4.0}/examples/01_social_network.py +0 -0
  199. {graphforge-0.3.9 → graphforge-0.4.0}/examples/02_knowledge_graph.py +0 -0
  200. {graphforge-0.3.9 → graphforge-0.4.0}/examples/03_data_lineage.py +0 -0
  201. {graphforge-0.3.9 → graphforge-0.4.0}/examples/04_citation_network.py +0 -0
  202. {graphforge-0.3.9 → graphforge-0.4.0}/examples/agent_grounding/ecommerce_agent.ipynb +0 -0
  203. {graphforge-0.3.9 → graphforge-0.4.0}/examples/basic_graph.py +0 -0
  204. {graphforge-0.3.9 → graphforge-0.4.0}/examples/basic_usage.py +0 -0
  205. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/build_feature_graph.py +0 -0
  206. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/bump_version.py +0 -0
  207. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/check_release_needed.py +0 -0
  208. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/inventory_tck.py +0 -0
  209. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/perf_report.py +0 -0
  210. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/pre-push-check.sh +0 -0
  211. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/tck_metrics.py +0 -0
  212. {graphforge-0.3.9 → graphforge-0.4.0}/scripts/validate_datasets.py +0 -0
  213. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/ast/__init__.py +0 -0
  214. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/ast/clause.py +0 -0
  215. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/ast/pattern.py +0 -0
  216. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/ast/query.py +0 -0
  217. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/__init__.py +0 -0
  218. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/base.py +0 -0
  219. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/data/__init__.py +0 -0
  220. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/data/networkrepository.json +0 -0
  221. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/data/snap.json +0 -0
  222. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/exporters/__init__.py +0 -0
  223. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/formats/__init__.py +0 -0
  224. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/formats/json_graph.py +0 -0
  225. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/__init__.py +0 -0
  226. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/compression.py +0 -0
  227. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/csv.py +0 -0
  228. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/cypher.py +0 -0
  229. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/graphml.py +0 -0
  230. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/json_graph.py +0 -0
  231. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/ldbc.py +0 -0
  232. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/loaders/ldbc_schema.py +0 -0
  233. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/registry.py +0 -0
  234. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/__init__.py +0 -0
  235. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/graphml.py +0 -0
  236. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/json_graph.py +0 -0
  237. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/ldbc.py +0 -0
  238. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/networkrepository.py +0 -0
  239. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/datasets/sources/snap.py +0 -0
  240. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/executor/__init__.py +0 -0
  241. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/executor/evaluator.py +0 -0
  242. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/__init__.py +0 -0
  243. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/cost_model.py +0 -0
  244. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/join_reorder.py +0 -0
  245. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/predicate_utils.py +0 -0
  246. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/optimizer/statistics.py +0 -0
  247. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/parser/__init__.py +0 -0
  248. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/planner/__init__.py +0 -0
  249. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/planner/operators.py +0 -0
  250. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/planner/types.py +0 -0
  251. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/procedures/__init__.py +0 -0
  252. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/procedures/registry.py +0 -0
  253. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/storage/__init__.py +0 -0
  254. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/storage/memory.py +0 -0
  255. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/storage/pydantic_serialization.py +0 -0
  256. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/storage/serialization.py +0 -0
  257. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/storage/sqlite_backend.py +0 -0
  258. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/types/__init__.py +0 -0
  259. {graphforge-0.3.9 → graphforge-0.4.0}/src/graphforge/types/graph.py +0 -0
  260. {graphforge-0.3.9 → graphforge-0.4.0}/tests/README.md +0 -0
  261. {graphforge-0.3.9 → graphforge-0.4.0}/tests/__init__.py +0 -0
  262. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/__init__.py +0 -0
  263. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_compression.py +0 -0
  264. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_cypher_loader_docs.py +0 -0
  265. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_end_to_end_workflows.py +0 -0
  266. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_graphml_loader.py +0 -0
  267. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_json_graph_exporter.py +0 -0
  268. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_json_graph_loader.py +0 -0
  269. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_json_graph_roundtrip.py +0 -0
  270. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_ldbc_loader.py +0 -0
  271. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/datasets/test_networkrepository_loader.py +0 -0
  272. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/executor/test_graph_functions.py +0 -0
  273. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_aggregation_edge_cases.py +0 -0
  274. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_aggregation_functions_advanced.py +0 -0
  275. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_anonymous_relationships.py +0 -0
  276. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_arithmetic.py +0 -0
  277. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_builder_api.py +0 -0
  278. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_call_procedures.py +0 -0
  279. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_call_subqueries.py +0 -0
  280. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_case_expressions.py +0 -0
  281. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_collect.py +0 -0
  282. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_column_naming.py +0 -0
  283. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_compact_iso8601.py +0 -0
  284. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_complex_merge_patterns.py +0 -0
  285. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_complex_where_predicates.py +0 -0
  286. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_create_clause.py +0 -0
  287. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_create_edge_cases.py +0 -0
  288. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_delete_null.py +0 -0
  289. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_detach_delete.py +0 -0
  290. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_e2e_queries.py +0 -0
  291. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_executor_edge_cases.py +0 -0
  292. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_graph_element_comparison.py +0 -0
  293. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_hex_octal_literals.py +0 -0
  294. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_iana_timezones.py +0 -0
  295. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_id_function.py +0 -0
  296. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_issues_271_274.py +0 -0
  297. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_label_disjunction.py +0 -0
  298. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_label_predicate.py +0 -0
  299. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_comprehension.py +0 -0
  300. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_concatenation.py +0 -0
  301. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_functions.py +0 -0
  302. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_operations.py +0 -0
  303. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_path_overloading.py +0 -0
  304. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_list_subscript.py +0 -0
  305. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_logical_operators.py +0 -0
  306. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_map_subscript.py +0 -0
  307. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_match_create.py +0 -0
  308. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_math_functions.py +0 -0
  309. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_math_functions_extended.py +0 -0
  310. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_math_functions_new.py +0 -0
  311. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_merge_edge_cases.py +0 -0
  312. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_merge_on_create_real.py +0 -0
  313. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_merge_on_match_real.py +0 -0
  314. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_mixed_type_sort.py +0 -0
  315. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_nan_handling.py +0 -0
  316. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_null_handling.py +0 -0
  317. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_operator_precedence.py +0 -0
  318. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_optimizer_aggregate_pushdown.py +0 -0
  319. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_optimizer_integration.py +0 -0
  320. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_optimizer_redundant_elimination.py +0 -0
  321. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_optional_match.py +0 -0
  322. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_optional_match_delete.py +0 -0
  323. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_path_binding.py +0 -0
  324. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_path_binding_variable_length.py +0 -0
  325. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_path_functions.py +0 -0
  326. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_pattern_comprehension.py +0 -0
  327. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_pattern_predicates.py +0 -0
  328. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_persistence.py +0 -0
  329. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_power_operator.py +0 -0
  330. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_predicate_functions.py +0 -0
  331. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_properties_keys_functions.py +0 -0
  332. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_relationship_directions.py +0 -0
  333. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_relationship_uniqueness.py +0 -0
  334. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_remove_clause.py +0 -0
  335. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_set_delete_merge.py +0 -0
  336. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_size_function.py +0 -0
  337. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_skip_limit_expressions.py +0 -0
  338. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_snap_dataset_loading.py +0 -0
  339. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_sort_after_aggregation.py +0 -0
  340. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_spatial_api.py +0 -0
  341. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_sqlite_persistence.py +0 -0
  342. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_startnode_endnode_functions.py +0 -0
  343. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_string_functions.py +0 -0
  344. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_string_functions_new.py +0 -0
  345. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_string_matching.py +0 -0
  346. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_subquery_expressions.py +0 -0
  347. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_temporal_map_constructors.py +0 -0
  348. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_temporal_queries.py +0 -0
  349. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_temporal_select_into.py +0 -0
  350. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_transactions.py +0 -0
  351. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_type_conversion_fixes.py +0 -0
  352. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_type_functions.py +0 -0
  353. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_union.py +0 -0
  354. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_unwind.py +0 -0
  355. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_variable_length_paths.py +0 -0
  356. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_varlen_predicate_and_uniqueness.py +0 -0
  357. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_wildcard_execution.py +0 -0
  358. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_with_aggregation_real.py +0 -0
  359. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_with_clause_modifiers.py +0 -0
  360. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_with_clause_positions.py +0 -0
  361. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_with_distinct_skip_limit.py +0 -0
  362. {graphforge-0.3.9 → graphforge-0.4.0}/tests/integration/test_xor_operator.py +0 -0
  363. {graphforge-0.3.9/tests/unit/procedures → graphforge-0.4.0/tests/perf}/__init__.py +0 -0
  364. {graphforge-0.3.9 → graphforge-0.4.0}/tests/perf/conftest.py +0 -0
  365. {graphforge-0.3.9 → graphforge-0.4.0}/tests/perf/test_real_datasets.py +0 -0
  366. {graphforge-0.3.9 → graphforge-0.4.0}/tests/property/__init__.py +0 -0
  367. {graphforge-0.3.9 → graphforge-0.4.0}/tests/property/strategies.py +0 -0
  368. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/__init__.py +0 -0
  369. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/conftest.py +0 -0
  370. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/coverage_matrix.json +0 -0
  371. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/download_tck.py +0 -0
  372. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/Aggregation1_BasicAggregation.feature +0 -0
  373. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/Match1_SimpleMatches.feature +0 -0
  374. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call1.feature +0 -0
  375. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call2.feature +0 -0
  376. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call3.feature +0 -0
  377. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call4.feature +0 -0
  378. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call5.feature +0 -0
  379. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/call/Call6.feature +0 -0
  380. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create1.feature +0 -0
  381. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create2.feature +0 -0
  382. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create3.feature +0 -0
  383. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create4.feature +0 -0
  384. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create5.feature +0 -0
  385. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/create/Create6.feature +0 -0
  386. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete1.feature +0 -0
  387. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete2.feature +0 -0
  388. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete3.feature +0 -0
  389. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete4.feature +0 -0
  390. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete5.feature +0 -0
  391. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/delete/Delete6.feature +0 -0
  392. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match1.feature +0 -0
  393. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match2.feature +0 -0
  394. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match3.feature +0 -0
  395. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match4.feature +0 -0
  396. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match5.feature +0 -0
  397. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match6.feature +0 -0
  398. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match7.feature +0 -0
  399. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match8.feature +0 -0
  400. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match/Match9.feature +0 -0
  401. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere1.feature +0 -0
  402. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere2.feature +0 -0
  403. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere3.feature +0 -0
  404. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere4.feature +0 -0
  405. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere5.feature +0 -0
  406. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/match-where/MatchWhere6.feature +0 -0
  407. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge1.feature +0 -0
  408. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge2.feature +0 -0
  409. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge3.feature +0 -0
  410. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge4.feature +0 -0
  411. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge5.feature +0 -0
  412. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge6.feature +0 -0
  413. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge7.feature +0 -0
  414. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge8.feature +0 -0
  415. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/merge/Merge9.feature +0 -0
  416. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/remove/Remove1.feature +0 -0
  417. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/remove/Remove2.feature +0 -0
  418. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/remove/Remove3.feature +0 -0
  419. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return1.feature +0 -0
  420. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return2.feature +0 -0
  421. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return3.feature +0 -0
  422. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return4.feature +0 -0
  423. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return5.feature +0 -0
  424. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return6.feature +0 -0
  425. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return7.feature +0 -0
  426. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return/Return8.feature +0 -0
  427. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy1.feature +0 -0
  428. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy2.feature +0 -0
  429. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy3.feature +0 -0
  430. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy4.feature +0 -0
  431. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy5.feature +0 -0
  432. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy6.feature +0 -0
  433. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit1.feature +0 -0
  434. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit2.feature +0 -0
  435. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit3.feature +0 -0
  436. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set1.feature +0 -0
  437. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set2.feature +0 -0
  438. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set3.feature +0 -0
  439. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set4.feature +0 -0
  440. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set5.feature +0 -0
  441. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/set/Set6.feature +0 -0
  442. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/union/Union1.feature +0 -0
  443. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/union/Union2.feature +0 -0
  444. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/union/Union3.feature +0 -0
  445. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/unwind/Unwind1.feature +0 -0
  446. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With1.feature +0 -0
  447. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With2.feature +0 -0
  448. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With3.feature +0 -0
  449. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With4.feature +0 -0
  450. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With5.feature +0 -0
  451. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With6.feature +0 -0
  452. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with/With7.feature +0 -0
  453. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy1.feature +0 -0
  454. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy2.feature +0 -0
  455. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy3.feature +0 -0
  456. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy4.feature +0 -0
  457. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit1.feature +0 -0
  458. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit2.feature +0 -0
  459. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit3.feature +0 -0
  460. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere1.feature +0 -0
  461. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere2.feature +0 -0
  462. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere3.feature +0 -0
  463. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere4.feature +0 -0
  464. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere5.feature +0 -0
  465. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere6.feature +0 -0
  466. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/clauses/with-where/WithWhere7.feature +0 -0
  467. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation1.feature +0 -0
  468. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation2.feature +0 -0
  469. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation3.feature +0 -0
  470. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation4.feature +0 -0
  471. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation5.feature +0 -0
  472. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation6.feature +0 -0
  473. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation7.feature +0 -0
  474. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/aggregation/Aggregation8.feature +0 -0
  475. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/boolean/Boolean1.feature +0 -0
  476. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/boolean/Boolean2.feature +0 -0
  477. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/boolean/Boolean3.feature +0 -0
  478. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/boolean/Boolean4.feature +0 -0
  479. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/boolean/Boolean5.feature +0 -0
  480. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/comparison/Comparison1.feature +0 -0
  481. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/comparison/Comparison2.feature +0 -0
  482. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/comparison/Comparison3.feature +0 -0
  483. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/comparison/Comparison4.feature +0 -0
  484. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/conditional/Conditional1.feature +0 -0
  485. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/conditional/Conditional2.feature +0 -0
  486. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery1.feature +0 -0
  487. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery2.feature +0 -0
  488. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery3.feature +0 -0
  489. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph1.feature +0 -0
  490. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph2.feature +0 -0
  491. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph3.feature +0 -0
  492. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph4.feature +0 -0
  493. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph5.feature +0 -0
  494. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph6.feature +0 -0
  495. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph7.feature +0 -0
  496. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph8.feature +0 -0
  497. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/graph/Graph9.feature +0 -0
  498. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List1.feature +0 -0
  499. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List10.feature +0 -0
  500. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List11.feature +0 -0
  501. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List12.feature +0 -0
  502. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List2.feature +0 -0
  503. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List3.feature +0 -0
  504. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List4.feature +0 -0
  505. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List5.feature +0 -0
  506. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List6.feature +0 -0
  507. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List7.feature +0 -0
  508. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List8.feature +0 -0
  509. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/list/List9.feature +0 -0
  510. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals1.feature +0 -0
  511. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals2.feature +0 -0
  512. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals3.feature +0 -0
  513. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals4.feature +0 -0
  514. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals5.feature +0 -0
  515. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals6.feature +0 -0
  516. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals7.feature +0 -0
  517. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/literals/Literals8.feature +0 -0
  518. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/map/Map1.feature +0 -0
  519. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/map/Map2.feature +0 -0
  520. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/map/Map3.feature +0 -0
  521. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical1.feature +0 -0
  522. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical10.feature +0 -0
  523. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical11.feature +0 -0
  524. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical12.feature +0 -0
  525. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical13.feature +0 -0
  526. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical14.feature +0 -0
  527. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical15.feature +0 -0
  528. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical16.feature +0 -0
  529. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical17.feature +0 -0
  530. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical2.feature +0 -0
  531. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical3.feature +0 -0
  532. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical4.feature +0 -0
  533. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical5.feature +0 -0
  534. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical6.feature +0 -0
  535. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical7.feature +0 -0
  536. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical8.feature +0 -0
  537. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/mathematical/Mathematical9.feature +0 -0
  538. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/null/Null1.feature +0 -0
  539. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/null/Null2.feature +0 -0
  540. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/null/Null3.feature +0 -0
  541. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/path/Path1.feature +0 -0
  542. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/path/Path2.feature +0 -0
  543. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/path/Path3.feature +0 -0
  544. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/pattern/Pattern1.feature +0 -0
  545. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/pattern/Pattern2.feature +0 -0
  546. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/precedence/Precedence1.feature +0 -0
  547. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/precedence/Precedence2.feature +0 -0
  548. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/precedence/Precedence3.feature +0 -0
  549. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/precedence/Precedence4.feature +0 -0
  550. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier1.feature +0 -0
  551. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier10.feature +0 -0
  552. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier11.feature +0 -0
  553. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier12.feature +0 -0
  554. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier2.feature +0 -0
  555. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier3.feature +0 -0
  556. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier4.feature +0 -0
  557. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier5.feature +0 -0
  558. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier6.feature +0 -0
  559. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier7.feature +0 -0
  560. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier8.feature +0 -0
  561. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/quantifier/Quantifier9.feature +0 -0
  562. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String1.feature +0 -0
  563. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String10.feature +0 -0
  564. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String11.feature +0 -0
  565. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String12.feature +0 -0
  566. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String13.feature +0 -0
  567. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String14.feature +0 -0
  568. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String2.feature +0 -0
  569. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String3.feature +0 -0
  570. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String4.feature +0 -0
  571. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String5.feature +0 -0
  572. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String6.feature +0 -0
  573. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String7.feature +0 -0
  574. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String8.feature +0 -0
  575. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/string/String9.feature +0 -0
  576. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal1.feature +0 -0
  577. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal10.feature +0 -0
  578. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal2.feature +0 -0
  579. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal3.feature +0 -0
  580. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal4.feature +0 -0
  581. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal5.feature +0 -0
  582. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal6.feature +0 -0
  583. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal7.feature +0 -0
  584. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal8.feature +0 -0
  585. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/temporal/Temporal9.feature +0 -0
  586. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion1.feature +0 -0
  587. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion2.feature +0 -0
  588. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion3.feature +0 -0
  589. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion4.feature +0 -0
  590. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion5.feature +0 -0
  591. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/expressions/typeConversion/TypeConversion6.feature +0 -0
  592. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/useCases/countingSubgraphMatches/CountingSubgraphMatches1.feature +0 -0
  593. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/features/official/useCases/triadicSelection/TriadicSelection1.feature +0 -0
  594. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/graphs/binary-tree-1/binary-tree-1.cypher +0 -0
  595. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/graphs/binary-tree-1/binary-tree-1.json +0 -0
  596. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/graphs/binary-tree-2/binary-tree-2.cypher +0 -0
  597. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/graphs/binary-tree-2/binary-tree-2.json +0 -0
  598. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/graphs/named-graphs.adoc +0 -0
  599. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/tck_config.yaml +0 -0
  600. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/tck_markers.py +0 -0
  601. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/test_features.py +0 -0
  602. {graphforge-0.3.9 → graphforge-0.4.0}/tests/tck/test_tck_compliance.py +0 -0
  603. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/__init__.py +0 -0
  604. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/__init__.py +0 -0
  605. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/test_api_coverage.py +0 -0
  606. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/test_bulk_ingest.py +0 -0
  607. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/test_clear.py +0 -0
  608. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/test_clone.py +0 -0
  609. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/api/test_cypher_value_conversion.py +0 -0
  610. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/ast/__init__.py +0 -0
  611. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/ast/test_ast_nodes.py +0 -0
  612. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/ast/test_expression_coverage.py +0 -0
  613. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/__init__.py +0 -0
  614. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_compression_coverage.py +0 -0
  615. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_csv_loader.py +0 -0
  616. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_cypher_loader.py +0 -0
  617. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_graphml_loader.py +0 -0
  618. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_json_graph_exporter.py +0 -0
  619. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_json_graph_format.py +0 -0
  620. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_json_graph_loader.py +0 -0
  621. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_ldbc_schema.py +0 -0
  622. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_networkrepository.py +0 -0
  623. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_snap_datasets.py +0 -0
  624. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/datasets/test_sources_registration.py +0 -0
  625. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/__init__.py +0 -0
  626. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_aggregation_errors.py +0 -0
  627. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_aggregation_functions_advanced.py +0 -0
  628. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_arithmetic_evaluator.py +0 -0
  629. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_element_id.py +0 -0
  630. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_evaluator.py +0 -0
  631. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_evaluator_additional_coverage.py +0 -0
  632. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_evaluator_coverage_boost.py +0 -0
  633. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_evaluator_error_paths.py +0 -0
  634. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_executor_coverage_boost.py +0 -0
  635. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_executor_error_paths.py +0 -0
  636. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_expression_matching.py +0 -0
  637. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_expressions_match.py +0 -0
  638. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_graph_functions.py +0 -0
  639. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_id_function.py +0 -0
  640. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_in_operator.py +0 -0
  641. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_infer_rel_var.py +0 -0
  642. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_limit_short_circuit.py +0 -0
  643. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_list_functions.py +0 -0
  644. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_list_functions_errors.py +0 -0
  645. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_map_property_access.py +0 -0
  646. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_merge_on_create.py +0 -0
  647. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_merge_on_match.py +0 -0
  648. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_multihop_create.py +0 -0
  649. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_optional_expand_bound_dst.py +0 -0
  650. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_optional_scan_coverage.py +0 -0
  651. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_parenthesized_expr_coverage.py +0 -0
  652. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_path_functions.py +0 -0
  653. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_procedure_call_executor.py +0 -0
  654. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_properties_keys_errors.py +0 -0
  655. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_property_index_executor.py +0 -0
  656. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_set_extensions.py +0 -0
  657. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_sort_edge_cases.py +0 -0
  658. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_spatial_functions.py +0 -0
  659. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_startnode_endnode_errors.py +0 -0
  660. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_string_functions_new.py +0 -0
  661. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_string_matching_evaluator.py +0 -0
  662. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_subquery_planner_check.py +0 -0
  663. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_temporal_functions.py +0 -0
  664. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_temporal_truncate_arithmetic.py +0 -0
  665. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_three_valued_logic.py +0 -0
  666. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_type_conversion_complex.py +0 -0
  667. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_undirected_relationship_bugs.py +0 -0
  668. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/executor/test_with_aggregation.py +0 -0
  669. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/__init__.py +0 -0
  670. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_aggregate_pushdown.py +0 -0
  671. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_cost_model.py +0 -0
  672. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_filter_pushdown.py +0 -0
  673. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_join_reorder.py +0 -0
  674. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_join_reorder_coverage.py +0 -0
  675. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_optimizer_coverage.py +0 -0
  676. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_optimizer_reuse.py +0 -0
  677. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_predicate_reorder.py +0 -0
  678. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_predicate_utils.py +0 -0
  679. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_predicate_utils_coverage.py +0 -0
  680. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/optimizer/test_statistics.py +0 -0
  681. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/__init__.py +0 -0
  682. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_arithmetic_parser.py +0 -0
  683. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_call_procedure_parser.py +0 -0
  684. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_case_parser.py +0 -0
  685. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_collect_parser.py +0 -0
  686. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_delete_parser.py +0 -0
  687. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_float_literals.py +0 -0
  688. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_grammar.py +0 -0
  689. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_hex_octal_literals.py +0 -0
  690. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_label_predicate_parser.py +0 -0
  691. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_merge_on_create.py +0 -0
  692. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_merge_on_match.py +0 -0
  693. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_optional_match_delete.py +0 -0
  694. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_order_by_direction.py +0 -0
  695. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_parser.py +0 -0
  696. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_parser_caching.py +0 -0
  697. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_parser_coverage_boost.py +0 -0
  698. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_path_binding.py +0 -0
  699. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_pattern_comprehension_binding.py +0 -0
  700. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_pattern_predicates.py +0 -0
  701. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_remove_parser.py +0 -0
  702. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_string_matching_parser.py +0 -0
  703. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_wildcard_parsing.py +0 -0
  704. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_with_at_query_start.py +0 -0
  705. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/parser/test_with_clause_positions.py +0 -0
  706. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/__init__.py +0 -0
  707. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_call_procedure_planner.py +0 -0
  708. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_expand_multi_hop_operator.py +0 -0
  709. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_operator_validation.py +0 -0
  710. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_operators.py +0 -0
  711. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_planner_branch_coverage.py +0 -0
  712. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_planner_comprehensive.py +0 -0
  713. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_planner_edge_cases.py +0 -0
  714. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_remove_planner.py +0 -0
  715. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_type_tracking.py +0 -0
  716. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/planner/test_with_validation.py +0 -0
  717. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/procedures/test_registry.py +0 -0
  718. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/__init__.py +0 -0
  719. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_graph_edge_cases.py +0 -0
  720. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_memory_store.py +0 -0
  721. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_property_index.py +0 -0
  722. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_pydantic_serialization.py +0 -0
  723. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_serialization_edge_cases.py +0 -0
  724. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_spatial_serialization.py +0 -0
  725. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_sqlite_backend_adjacency.py +0 -0
  726. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_sqlite_backend_delete_bulk.py +0 -0
  727. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_storage_coverage.py +0 -0
  728. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/storage/test_temporal_serialization.py +0 -0
  729. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/test_graph_elements.py +0 -0
  730. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/test_iana_timezone_construction.py +0 -0
  731. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/test_procedure_registry_coverage.py +0 -0
  732. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/test_values.py +0 -0
  733. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_cypher_values_deep_equality.py +0 -0
  734. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_cypher_values_edge_cases.py +0 -0
  735. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_extreme_temporal_values.py +0 -0
  736. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_graph_element_edge_cases.py +0 -0
  737. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_path_values.py +0 -0
  738. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_spatial_values.py +0 -0
  739. {graphforge-0.3.9 → graphforge-0.4.0}/tests/unit/types/test_temporal_values.py +0 -0
@@ -2,12 +2,14 @@
2
2
 
3
3
  ## Supported Versions
4
4
 
5
- GraphForge is currently in active development. Security updates are provided for the following versions:
5
+ GraphForge is pre-v1.0. The API is still maturing, and only the **latest release** receives security updates. If you discover a vulnerability, please update to the latest version first.
6
6
 
7
- | Version | Supported |
8
- | ------- | ------------------ |
9
- | 0.1.x | :white_check_mark: |
10
- | < 0.1 | :x: |
7
+ | Version | Supported |
8
+ | ------- | --------- |
9
+ | Latest (0.3.x) | :white_check_mark: |
10
+ | Older releases | :x: |
11
+
12
+ We will begin supporting multiple versions once a stable v1.0 API is reached.
11
13
 
12
14
  ## Reporting a Vulnerability
13
15
 
@@ -19,11 +21,7 @@ Please do not report security vulnerabilities through public GitHub issues.
19
21
 
20
22
  ### 2. Report Privately
21
23
 
22
- Send a detailed report to:
23
-
24
- **Email:** [Add your security contact email]
25
-
26
- Or use GitHub's private vulnerability reporting:
24
+ Use GitHub's private vulnerability reporting:
27
25
 
28
26
  1. Go to the [Security tab](https://github.com/DecisionNerd/graphforge/security)
29
27
  2. Click "Report a vulnerability"
@@ -126,7 +124,7 @@ GraphForge uses SQLite for persistence:
126
124
 
127
125
  ### 2. Query Execution
128
126
 
129
- - **No query timeout:** Long-running queries can cause DoS (roadmap item)
127
+ - **No query timeout:** Long-running queries can cause DoS
130
128
  - **No resource limits:** No built-in limits on memory/CPU usage
131
129
  - **No access control:** No user authentication/authorization system
132
130
 
@@ -134,18 +132,6 @@ GraphForge uses SQLite for persistence:
134
132
 
135
133
  - **MessagePack:** Uses msgpack for serialization (ensure trusted data only)
136
134
 
137
- ## Security Roadmap
138
-
139
- Future security enhancements planned:
140
-
141
- - [ ] Query timeout mechanisms
142
- - [ ] Resource usage limits (memory, CPU)
143
- - [ ] Query complexity analysis
144
- - [ ] Access control system
145
- - [ ] Audit logging
146
- - [ ] Encrypted database files
147
- - [ ] Security scanning in CI/CD (Dependabot, CodeQL)
148
-
149
135
  ## Security-Related Configuration
150
136
 
151
137
  ### Bandit (Security Linting)
@@ -174,19 +160,11 @@ safety check
174
160
  - **CVE assignment:** We'll request CVEs for significant vulnerabilities
175
161
  - **Security advisories:** Published on GitHub Security Advisories
176
162
 
177
- ## Contact
178
-
179
- For security-related questions (non-vulnerability):
180
-
181
- - **Email:** [Add your contact email]
182
- - **Discussions:** [GitHub Discussions](https://github.com/DecisionNerd/graphforge/discussions)
183
-
184
163
  ## Attribution
185
164
 
186
165
  We believe in recognizing security researchers who help improve GraphForge. With your permission, we'll:
187
166
 
188
167
  - Credit you in security advisories
189
- - List you in our security hall of fame (coming soon)
190
168
  - Mention you in release notes
191
169
 
192
170
  ## Additional Resources
@@ -197,6 +175,6 @@ We believe in recognizing security researchers who help improve GraphForge. With
197
175
 
198
176
  ---
199
177
 
200
- **Last Updated:** January 31, 2026
178
+ **Last Updated:** 2026-05-06
201
179
 
202
180
  Thank you for helping keep GraphForge secure!
@@ -6,12 +6,15 @@ on:
6
6
  paths:
7
7
  - 'docs/**'
8
8
  - 'mkdocs.yml'
9
+ - 'src/graphforge/**'
10
+ - 'pyproject.toml'
9
11
  - '.github/workflows/docs.yml'
10
12
  pull_request:
11
13
  branches: [main]
12
14
  paths:
13
15
  - 'docs/**'
14
16
  - 'mkdocs.yml'
17
+ - 'src/graphforge/**'
15
18
  workflow_dispatch:
16
19
 
17
20
  permissions:
@@ -19,7 +22,6 @@ permissions:
19
22
  pages: write
20
23
  id-token: write
21
24
 
22
- # Allow only one concurrent deployment
23
25
  concurrency:
24
26
  group: pages
25
27
  cancel-in-progress: false
@@ -28,30 +30,30 @@ jobs:
28
30
  build:
29
31
  name: Build Documentation
30
32
  runs-on: ubuntu-latest
31
-
32
33
  steps:
33
- - name: Checkout code
34
+ - name: Checkout
34
35
  uses: actions/checkout@v6
35
36
  with:
36
- fetch-depth: 0 # Fetch all history for git info
37
+ fetch-depth: 0
37
38
 
38
39
  - name: Install uv
39
40
  uses: astral-sh/setup-uv@v8.1.0
41
+ with:
42
+ enable-cache: true
40
43
 
41
44
  - name: Set up Python
42
45
  uses: actions/setup-python@v6
43
46
  with:
44
47
  python-version: '3.12'
45
48
 
46
- - name: Install documentation dependencies
47
- run: |
48
- uv pip install --system -e ".[docs]"
49
+ - name: Install docs dependencies
50
+ run: uv sync --group docs
49
51
 
50
52
  - name: Build documentation
51
- run: mkdocs build --strict
53
+ run: uv run mkdocs build --strict
52
54
 
53
55
  - name: Upload Pages artifact
54
- if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
56
+ if: github.event_name != 'pull_request'
55
57
  uses: actions/upload-pages-artifact@v5
56
58
  with:
57
59
  path: site/
@@ -59,7 +61,7 @@ jobs:
59
61
  deploy:
60
62
  name: Deploy to GitHub Pages
61
63
  needs: build
62
- if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
64
+ if: github.event_name != 'pull_request'
63
65
  runs-on: ubuntu-latest
64
66
 
65
67
  environment:
@@ -266,7 +266,7 @@ jobs:
266
266
 
267
267
  - name: Report TCK performance metrics
268
268
  if: always()
269
- run: uv run python3 scripts/tck_perf_report.py test-results-tck.xml --threshold 5
269
+ run: uv run python3 scripts/tck_perf_report.py test-results-tck.xml --threshold 2
270
270
 
271
271
  - name: Upload TCK results to Codecov
272
272
  uses: codecov/codecov-action@v6
@@ -173,6 +173,10 @@ profile_*
173
173
  *.log
174
174
  .temp/
175
175
  tmp/
176
+
177
+ # macOS Finder "keep both" duplicates (e.g. "file 2.py", "file 2.md", "file 3")
178
+ * [0-9]
179
+ * [0-9].*
176
180
  # MkDocs build output
177
181
  site/
178
182
  tck_*.txt
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-05-07
11
+
12
+ ### Added
13
+ - **`db.gds` graph algorithm surface** (#484, PRs #514–#516) — 8 compiled algorithms dispatched to igraph (preferred) or NetworkX: `pagerank`, `betweenness_centrality`, `closeness_centrality`, `degree_centrality`, `louvain`, `connected_components`, `clustering_coefficient`, `triangle_count`. Stream mode returns `dict[node_id, scalar]`; write mode persists results via `set_node_properties()`. Optional `node_label`, `rel_type`, `directed` filters.
14
+ - **`db.search` hybrid retrieval surface** (#476, PRs #517 #533–#539) — FTS5 text search (`db.search.text()`), vector cosine similarity (`db.search.vector()`), and RRF-fused hybrid (`db.search()` / `db.search.hybrid()`). All methods return `list[SearchHit]` with `.ref`, `.score`, `.sources`, `.text_score`, `.vector_score`. Multi-space vector storage: `set_node_vector(id, vec, space="model-name")`. Bring-your-own-vectors; `space` can represent text embeddings, geo coordinates, temporal features, or any numeric feature array.
15
+ - **`SearchHit` result type** — frozen dataclass with score provenance; every `.ref.id` is directly addressable in `db.execute()`.
16
+ - **`set_node_properties()` bulk write-back** (#480, PR #515) — batch-update node properties from a `dict[node_id, dict[prop, value]]`.
17
+ - **`directed` and `node_id_property` export parameters** (#478 #479, PR #514) — `to_networkx(directed=True)`, `to_igraph(node_id_property="name")`, etc.
18
+ - **`graphforge.recipes.neighbourhood()`** (#492, PR #518) — n-hop subgraph expansion returning `list[dict]` for LLM context building.
19
+ - **Benchmark suite** (#388, PR #519) — `make benchmark` runs real-dataset benchmarks through M-tier (XS/S/M/L).
20
+ - **Integration tests for three-surface interoperability** (PR #541) — GDS write-back readable via Cypher, search results addressable via `id()`, cross-surface PageRank threshold queries.
21
+ - **Use-case documentation** (PR #542, closes #523 #524 #525 #526) — `db.gds` examples in `network-analysis.md`; `db.search` + `recipes` in `llm-workflows.md`; deduplication pattern in `knowledge-graph-construction.md`; hybrid tool selection in `agent-grounding.md`.
22
+
23
+ ## [0.3.10] - 2026-05-06
24
+
25
+ ### Added
26
+ - **Schema introspection API** (#469, #499) — `labels()`, `relationship_types()`, `node_count(label=None)`, `relationship_count(type=None)` on `GraphForge`; efficient set-union over storage backend
27
+ - **JSON export/import** (#470, #500) — `gf.to_json(path, metadata, indent)` serialises the full graph to a portable JSON file; `GraphForge.from_json(path)` reconstructs it; Hypothesis roundtrip property test
28
+ - **`merge_node()` safe upsert** (#471, #501) — `merge_node(labels, match_on, on_create, on_match)` with regex label validation, index-safe on_match updates, and create/match semantics matching MERGE clause behaviour
29
+ - **`add_graph_documents()` LangChain-compatible ingestion** (#472, #502) — duck-typed batch ingestion accepting any object with `.nodes`/`.relationships` attributes; idempotent edges; rel type pre-check; no `langchain-community` import required
30
+ - **Parse/plan LRU cache** (#464, #504) — `GraphForge(cache_size=N)` caches parsed+planned query pipelines; `clear_cache()` and `cache_info()` for introspection; thread-safe; default size 128
31
+
32
+ ### Fixed
33
+ - **ORDER BY on aliased RETURN DISTINCT property no longer raises UndefinedVariable** (#481, #494) — planner now records `(variable, property)` paths for aliased `PropertyAccess` return items, so `RETURN DISTINCT a.year AS year ORDER BY a.year` resolves correctly
34
+ - **Variable reuse across WITH boundary no longer raises KeyError** (#482, #495) — optimizer's redundant-traversal-elimination pass now treats `Aggregate` as a scope boundary (same as `With`/`Union`/`Subquery`), preventing fresh post-WITH variable bindings from being silently dropped
35
+ - **EXISTS {} subquery crash on anonymous inner node with outer-scope property** (#474, #496) — `_plan_match` now passes `var_name` (always set, from pattern variable or generated) instead of `node_pattern.variable` (can be None) to `_properties_to_predicate`
36
+ - **`shortestPath()` / `allShortestPaths()` parse correctly and raise NotImplementedError** (#468, #497) — previously caused unhelpful `SyntaxError: Unexpected token`; now parsed into `ShortestPathExpression` AST nodes; planner raises `NotImplementedError` with BFS workaround: `MATCH path = (a)-[*1..N]-(b) RETURN length(path) ORDER BY length(path) LIMIT 1`
37
+
10
38
  ## [0.3.9] - 2026-05-04
11
39
 
12
40
  ### Added
@@ -111,7 +111,17 @@ PYTEST_WORKERS=2 make test
111
111
 
112
112
  **When to use `pre-push-fast`:** iterating on non-test changes (refactors, docs, config). Always run the full `pre-push` before opening a PR.
113
113
 
114
- ## Architecture: 4-Layer System
114
+ ## Architecture: Three-Surface API
115
+
116
+ GraphForge has three independent API surfaces that share a single storage layer. **Each surface has a distinct code path. Not every feature flows through all four Cypher layers.**
117
+
118
+ ```
119
+ db.execute("MATCH ...") → Cypher path (4-layer pipeline below)
120
+ db.gds.pagerank(...) → Algorithm path (bypasses parser/planner/executor)
121
+ db.search(...) → Search path (bypasses parser/planner/executor)
122
+ ```
123
+
124
+ ### Cypher Path (db.execute)
115
125
 
116
126
  ```
117
127
  User Code (Python API / Cypher)
@@ -142,12 +152,90 @@ User Code (Python API / Cypher)
142
152
  └─────────────────────────────────────────────────┘
143
153
  ```
144
154
 
155
+ ### Algorithm Path (db.gds)
156
+
157
+ `db.gds.*` methods do **not** follow the 4-layer pattern. They live in `src/graphforge/algorithms/` and bypass the parser, planner, and executor entirely.
158
+
159
+ ```
160
+ _export_for_algorithm(node_label, rel_type, directed)
161
+ ↓
162
+ _resolve_backend() → native (future) → igraph → NetworkX
163
+ ↓
164
+ backend.compute(G, **kwargs) → dict[node_id, scalar]
165
+ ↓
166
+ set_node_properties({nid: {write_property: val} …}) ← if write_property set
167
+ ```
168
+
169
+ Key files:
170
+ - `src/graphforge/algorithms/gds.py` — `GraphDataScience` accessor class
171
+ - `src/graphforge/algorithms/_dispatch.py` — `_resolve_backend()` + dispatch helpers
172
+ - `src/graphforge/algorithms/centrality.py` — pagerank, betweenness, closeness, degree
173
+ - `src/graphforge/algorithms/community.py` — louvain, connected_components
174
+ - `src/graphforge/algorithms/structural.py` — clustering_coefficient, triangle_count
175
+
176
+ #### Adding a db.gds Algorithm
177
+
178
+ 1. Implement in `algorithms/<category>.py`
179
+ 2. Add dispatch branch in `_dispatch.py` for each supported backend
180
+ 3. Expose method on `GraphDataScience` class in `gds.py`
181
+ 4. Tests: unit test per backend + integration test via `db.gds.<name>()`
182
+
183
+ #### Adding a New Backend Tier
184
+
185
+ 1. Add detection logic in `_resolve_backend()`
186
+ 2. Implement algorithm dispatch in the new backend branch
187
+ 3. Test priority fallback (native → igraph → NX)
188
+ 4. API and existing tests do not change
189
+
190
+ ### Search Path (db.search)
191
+
192
+ `db.search.*` operates on SQLite FTS5 virtual tables and BLOB vector columns — not the graph execution engine. It does not parse Cypher.
193
+
194
+ Primary entry point: `db.search(query, vector=...)` — hybrid by default.
195
+ Named methods: `db.search.text(query)`, `db.search.vector(vec)`, `db.search.hybrid(query, vec)`.
196
+ All methods return `list[SearchHit]` with `.ref`, `.score`, `.sources`, `.text_score`, `.vector_score`.
197
+
198
+ **Bring-your-own-vectors contract:** GraphForge stores and queries vectors but does not generate them.
199
+ The `space` parameter identifies what a vector *represents* — vectors are not limited to text embeddings.
200
+ Common uses: text embeddings (`"text-embedding-3-small"`, SBERT), geographic coordinates (`[lat, lon]`),
201
+ temporal features (`[unix_timestamp, ...]`), or any numeric feature array. For each space, cosine
202
+ similarity finds the closest stored vectors to a query vector. Callers are responsible for consistent
203
+ encoding and dimensionality between stored and query vectors. `db.search.text()` works standalone.
204
+ A recipe for embedding + indexing in one call is tracked in issue #540.
205
+
206
+ Key files:
207
+ - `src/graphforge/search/search.py` — `GraphSearch` class (text, vector, hybrid, index_node, index_all)
208
+ - `src/graphforge/search/types.py` — `SearchHit` frozen dataclass
209
+ - FTS5 virtual tables: `node_fts`, `edge_fts`
210
+ - Vector store: `node_vector`, `edge_vector` (BLOB columns + NumPy, composite PK `(node_id, space)`)
211
+
212
+ ### Recipes Module (graphforge.recipes)
213
+
214
+ `graphforge.recipes` is a collection of standalone helper functions (not a `db.*` accessor). Each recipe composes Cypher + API calls into a reusable pattern. Import directly from `graphforge.recipes`.
215
+
216
+ Key files:
217
+ - `src/graphforge/recipes/__init__.py` — All recipe functions
218
+
219
+ Current recipes:
220
+ - `neighbourhood(db, canonical, hops, *, label, canonical_prop)` — n-hop neighbourhood expansion returning `list[dict]`
221
+
222
+ ### Design Constraint: No Cypher Extensions
223
+
224
+ **Neither `db.gds` nor `db.search` modifies `cypher.lark`.** If you are adding a feature and find yourself editing the grammar, you are in the wrong surface.
225
+
226
+ | Feature type | Surface | Touches parser? |
227
+ |---|---|---|
228
+ | New Cypher clause or function | `db.execute` | Yes — all 4 layers |
229
+ | New graph algorithm | `db.gds` | No |
230
+ | New search capability | `db.search` | No |
231
+
145
232
  ### Key Principles
146
233
 
147
234
  1. **Each layer is independent** - Parser knows nothing about execution
148
235
  2. **AST is the contract** - Parser produces AST, planner consumes it
149
236
  3. **Operators are composable** - Planner emits list, executor chains them
150
237
  4. **Storage is pluggable** - Executor uses Graph interface
238
+ 5. **Surfaces are independent** - `db.gds` and `db.search` bypass the Cypher pipeline
151
239
 
152
240
  ### Adding Cypher Features
153
241
 
@@ -364,6 +452,27 @@ def test_create_node():
364
452
 
365
453
  ## Common Development Tasks
366
454
 
455
+ ### Adding a db.gds Algorithm
456
+
457
+ 1. Implement in `src/graphforge/algorithms/<category>.py`
458
+ 2. Add dispatch in `_dispatch.py` for each backend
459
+ 3. Expose method on `GraphDataScience` in `gds.py`
460
+ 4. Tests: unit per backend + integration via `db.gds.<name>()`
461
+
462
+ ### Adding a db.search Feature
463
+
464
+ 1. Add schema migration in search layer (FTS or vector table)
465
+ 2. Implement in `src/graphforge/search/<feature>.py`
466
+ 3. Expose method on `GraphSearch` accessor
467
+ 4. Tests: unit + integration; verify `NodeRef` results are addressable in `db.execute()`
468
+
469
+ ### Adding a Recipe
470
+
471
+ 1. Implement in `src/graphforge/recipes/__init__.py`
472
+ 2. Compose from `db.execute()`, `db.gds.*`, or `db.search.*` — recipes are convenience wrappers
473
+ 3. Tests: unit test in `tests/unit/recipes/`
474
+ 4. Recipe should return plain Python types (list, dict), not CypherValues
475
+
367
476
  ### Adding a New Cypher Clause
368
477
 
369
478
  1. Grammar: Add to `cypher.lark`
@@ -1,4 +1,4 @@
1
- .PHONY: help lint format type-check security test pre-push pre-push-fast clean test-tck docstring-coverage test-network test-perf test-perf-xs test-perf-slow test-perf-large coverage coverage-quick coverage-report coverage-diff coverage-strict check-coverage check-patch-coverage test-durations test-analytics
1
+ .PHONY: help lint format type-check security test pre-push pre-push-fast clean test-tck docstring-coverage test-network benchmark test-perf test-perf-xs test-perf-slow test-perf-large coverage coverage-quick coverage-report coverage-diff coverage-strict check-coverage check-patch-coverage test-durations test-analytics docs-serve docs-build docs-clean
2
2
 
3
3
  help: ## Show this help message
4
4
  @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
@@ -33,6 +33,9 @@ test-integration: ## Run integration tests in parallel (excludes snap/network d
33
33
  test-network: ## Run external network/download tests (snap datasets; requires internet)
34
34
  uv run pytest tests/ -m "snap" -v
35
35
 
36
+ benchmark: ## Run db.gds algorithm benchmarks on snap-ego-facebook; updates benchmarks/baseline.md
37
+ PYTHONPATH=src uv run python benchmarks/algorithms/bench_gds.py
38
+
36
39
  test-perf-xs: ## Run perf QA for XS/S datasets only (karate + ego-facebook, ~3 MB total)
37
40
  uv run pytest tests/perf/ -m "perf and not perf_large and not perf_slow" -k "xs or s_face" -v -s
38
41
 
@@ -178,3 +181,12 @@ clean: ## Clean up cache files
178
181
  find . -type f -name "*.pyc" -delete 2>/dev/null || true
179
182
  rm -f test-results*.xml coverage.xml 2>/dev/null || true
180
183
  rm -rf htmlcov/ 2>/dev/null || true
184
+
185
+ docs-serve: ## Serve docs locally with live reload (http://127.0.0.1:8000)
186
+ uv run --group docs mkdocs serve
187
+
188
+ docs-build: ## Build docs site to site/ (strict mode)
189
+ uv run --group docs mkdocs build --strict
190
+
191
+ docs-clean: ## Remove built docs
192
+ rm -rf site/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphforge
3
- Version: 0.3.9
3
+ Version: 0.4.0
4
4
  Summary: Composable graph tooling for analysis, construction, and refinement
5
5
  Project-URL: Homepage, https://github.com/DecisionNerd/graphforge
6
6
  Project-URL: Repository, https://github.com/DecisionNerd/graphforge
@@ -29,6 +29,10 @@ Requires-Dist: msgpack>=1.0
29
29
  Requires-Dist: pydantic>=2.6
30
30
  Requires-Dist: python-dateutil>=2.8.2
31
31
  Requires-Dist: pyyaml>=6.0.3
32
+ Provides-Extra: analytics
33
+ Requires-Dist: networkx>=3.0; extra == 'analytics'
34
+ Requires-Dist: pandas>=2.0; extra == 'analytics'
35
+ Requires-Dist: python-igraph>=0.11; extra == 'analytics'
32
36
  Provides-Extra: dev
33
37
  Requires-Dist: hypothesis>=6.0; extra == 'dev'
34
38
  Requires-Dist: pytest-bdd>=7.0; extra == 'dev'
@@ -39,11 +43,12 @@ Requires-Dist: pytest-timeout>=2.0; extra == 'dev'
39
43
  Requires-Dist: pytest-xdist>=3.0; extra == 'dev'
40
44
  Requires-Dist: pytest>=9.0.3; extra == 'dev'
41
45
  Requires-Dist: ruff==0.15.12; extra == 'dev'
42
- Provides-Extra: docs
43
- Requires-Dist: mkdocs-autorefs>=1.0.0; extra == 'docs'
44
- Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
45
- Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
46
- Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
46
+ Provides-Extra: igraph
47
+ Requires-Dist: python-igraph>=0.11; extra == 'igraph'
48
+ Provides-Extra: networkx
49
+ Requires-Dist: networkx>=3.0; extra == 'networkx'
50
+ Provides-Extra: pandas
51
+ Requires-Dist: pandas>=2.0; extra == 'pandas'
47
52
  Description-Content-Type: text/markdown
48
53
 
49
54
  <h1 align="center">GraphForge</h1>
@@ -104,9 +109,13 @@ Modern data science and ML workflows increasingly produce graph-shaped data —
104
109
 
105
110
  † *Traversal queries with LIMIT scale to ~20M edges; full-scan aggregations are practical up to ~1M edges.*
106
111
 
107
- ### v0.3.9 — Performance Release
112
+ ### v0.4.0 — Three-Surface API
108
113
 
109
- v0.3.9 delivers substantial performance improvements over v0.3.8: LALR(1) linear-time parsing, O(1) property equality index, LIMIT short-circuit for traversal and UNWIND, bulk ingestion API, SQLite PRAGMA tuning, and `elementId()`. TCK compliance is maintained at **3,885/3,885 (100%)**.
114
+ v0.4.0 ships two new API surfaces alongside the existing Cypher executor:
115
+
116
+ - **`db.gds`** — 8 compiled graph algorithms (PageRank, betweenness, Louvain, triangle count, and more) dispatched to igraph or NetworkX. Results write back to node properties and are immediately queryable via Cypher.
117
+ - **`db.search`** — hybrid retrieval combining FTS5 text search and vector cosine similarity via RRF fusion. Returns `SearchHit` objects with score provenance; every result is addressable in `db.execute()`.
118
+ - **`graphforge.recipes`** — composable helper functions; `neighbourhood()` builds n-hop context for LLM prompts.
110
119
 
111
120
  See [CHANGELOG.md](CHANGELOG.md) for the full list of changes.
112
121
 
@@ -176,6 +185,36 @@ bob = db.create_node(['Person'], name='Bob', age=25)
176
185
  db.create_relationship(alice, bob, 'KNOWS', since=2020)
177
186
  ```
178
187
 
188
+ ### Graph algorithms
189
+
190
+ ```python
191
+ # Compute PageRank and write scores back to nodes
192
+ db.gds.pagerank(write_property="rank")
193
+
194
+ # Query the written scores via Cypher
195
+ top = db.execute("MATCH (n) RETURN n.name, n.rank ORDER BY n.rank DESC LIMIT 5")
196
+
197
+ # Stream mode — returns dict[node_id, score] without mutating the graph
198
+ bc = db.gds.betweenness_centrality()
199
+ ```
200
+
201
+ ### Hybrid search
202
+
203
+ ```python
204
+ db = GraphForge("research.db")
205
+
206
+ # Index node text for full-text search
207
+ db.search.index_all(node_label="Paper", properties=["title", "abstract"])
208
+
209
+ # Store a precomputed embedding (bring your own model)
210
+ db.search.set_node_vector(node_id, embedding, space="text-embedding-3-small")
211
+
212
+ # Hybrid retrieval — text + vector signals fused via RRF
213
+ results = db.search("graph neural networks", vector=query_embedding, top_k=10)
214
+ for hit in results:
215
+ print(hit.ref.properties["title"].value, hit.score, hit.sources)
216
+ ```
217
+
179
218
  ### Access result values
180
219
 
181
220
  Results contain `CypherValue` objects — use `.value` to get the Python value:
@@ -326,7 +365,15 @@ finally:
326
365
 
327
366
  ## Architecture
328
367
 
329
- GraphForge is built in four independent layers:
368
+ GraphForge exposes three independent API surfaces over a shared storage layer:
369
+
370
+ ```
371
+ db.execute("MATCH ...") → Cypher path (Parser → Planner → Executor → Storage)
372
+ db.gds.pagerank(...) → Algorithm path (export → compiled backend → write-back)
373
+ db.search.fts(...) → Search path (SQLite FTS5 / vector index → NodeRef list)
374
+ ```
375
+
376
+ The Cypher path is four independent layers:
330
377
 
331
378
  ```
332
379
  ┌─────────────────────────────────────────────────┐
@@ -336,11 +383,11 @@ GraphForge is built in four independent layers:
336
383
  ├─────────────────────────────────────────────────┤
337
384
  │ Executor executor.py + evaluator.py │ Plan → Results
338
385
  ├─────────────────────────────────────────────────┤
339
- │ Storage memory.py + sqlite_backend.py │ In-memory + SQLite
386
+ │ Storage memory.py + sqlite_backend.py │ In-memory + SQLite WAL
340
387
  └─────────────────────────────────────────────────┘
341
388
  ```
342
389
 
343
- Storage uses **MessagePack** for efficient binary encoding of graph properties. Persistence is a single SQLite file with WAL mode for durability.
390
+ The algorithm and search paths bypass the Cypher executor entirely — `db.gds` and `db.search` are Python-method surfaces, not Cypher extensions. Storage uses **MessagePack** for efficient binary encoding of graph properties.
344
391
 
345
392
  ---
346
393
 
@@ -369,9 +416,8 @@ make coverage
369
416
  |---------|-------|--------|
370
417
  | v0.3.8 | Full TCK compliance (3,885/3,885) | **Released** |
371
418
  | v0.3.9 | Performance: LALR parser, property indexes, bulk ingest, SQLite tuning, LIMIT short-circuit | **Released** |
372
- | v0.3.10 | Analytics integration: NetworkX/igraph export, parse/plan cache | Planned |
373
- | v0.4.0 | Native SNA algorithms: PageRank, betweenness, WCC, shortest path via `CALL gf.algo.*` | Planned |
374
- | v1.0 | Production-ready: thread safety, large graph support | Future |
419
+ | v0.3.10 | Analytics integration: NetworkX/igraph export, parse/plan cache, `add_graph_documents()` | **Released** |
420
+ | v0.4.0 | Three-surface API: `db.gds.*` graph algorithms + `db.search.*` hybrid retrieval | **Released** |
375
421
 
376
422
  See [CHANGELOG.md](CHANGELOG.md) for full release history.
377
423
 
@@ -56,9 +56,13 @@ Modern data science and ML workflows increasingly produce graph-shaped data —
56
56
 
57
57
  † *Traversal queries with LIMIT scale to ~20M edges; full-scan aggregations are practical up to ~1M edges.*
58
58
 
59
- ### v0.3.9 — Performance Release
59
+ ### v0.4.0 — Three-Surface API
60
60
 
61
- v0.3.9 delivers substantial performance improvements over v0.3.8: LALR(1) linear-time parsing, O(1) property equality index, LIMIT short-circuit for traversal and UNWIND, bulk ingestion API, SQLite PRAGMA tuning, and `elementId()`. TCK compliance is maintained at **3,885/3,885 (100%)**.
61
+ v0.4.0 ships two new API surfaces alongside the existing Cypher executor:
62
+
63
+ - **`db.gds`** — 8 compiled graph algorithms (PageRank, betweenness, Louvain, triangle count, and more) dispatched to igraph or NetworkX. Results write back to node properties and are immediately queryable via Cypher.
64
+ - **`db.search`** — hybrid retrieval combining FTS5 text search and vector cosine similarity via RRF fusion. Returns `SearchHit` objects with score provenance; every result is addressable in `db.execute()`.
65
+ - **`graphforge.recipes`** — composable helper functions; `neighbourhood()` builds n-hop context for LLM prompts.
62
66
 
63
67
  See [CHANGELOG.md](CHANGELOG.md) for the full list of changes.
64
68
 
@@ -128,6 +132,36 @@ bob = db.create_node(['Person'], name='Bob', age=25)
128
132
  db.create_relationship(alice, bob, 'KNOWS', since=2020)
129
133
  ```
130
134
 
135
+ ### Graph algorithms
136
+
137
+ ```python
138
+ # Compute PageRank and write scores back to nodes
139
+ db.gds.pagerank(write_property="rank")
140
+
141
+ # Query the written scores via Cypher
142
+ top = db.execute("MATCH (n) RETURN n.name, n.rank ORDER BY n.rank DESC LIMIT 5")
143
+
144
+ # Stream mode — returns dict[node_id, score] without mutating the graph
145
+ bc = db.gds.betweenness_centrality()
146
+ ```
147
+
148
+ ### Hybrid search
149
+
150
+ ```python
151
+ db = GraphForge("research.db")
152
+
153
+ # Index node text for full-text search
154
+ db.search.index_all(node_label="Paper", properties=["title", "abstract"])
155
+
156
+ # Store a precomputed embedding (bring your own model)
157
+ db.search.set_node_vector(node_id, embedding, space="text-embedding-3-small")
158
+
159
+ # Hybrid retrieval — text + vector signals fused via RRF
160
+ results = db.search("graph neural networks", vector=query_embedding, top_k=10)
161
+ for hit in results:
162
+ print(hit.ref.properties["title"].value, hit.score, hit.sources)
163
+ ```
164
+
131
165
  ### Access result values
132
166
 
133
167
  Results contain `CypherValue` objects — use `.value` to get the Python value:
@@ -278,7 +312,15 @@ finally:
278
312
 
279
313
  ## Architecture
280
314
 
281
- GraphForge is built in four independent layers:
315
+ GraphForge exposes three independent API surfaces over a shared storage layer:
316
+
317
+ ```
318
+ db.execute("MATCH ...") → Cypher path (Parser → Planner → Executor → Storage)
319
+ db.gds.pagerank(...) → Algorithm path (export → compiled backend → write-back)
320
+ db.search.fts(...) → Search path (SQLite FTS5 / vector index → NodeRef list)
321
+ ```
322
+
323
+ The Cypher path is four independent layers:
282
324
 
283
325
  ```
284
326
  ┌─────────────────────────────────────────────────┐
@@ -288,11 +330,11 @@ GraphForge is built in four independent layers:
288
330
  ├─────────────────────────────────────────────────┤
289
331
  │ Executor executor.py + evaluator.py │ Plan → Results
290
332
  ├─────────────────────────────────────────────────┤
291
- │ Storage memory.py + sqlite_backend.py │ In-memory + SQLite
333
+ │ Storage memory.py + sqlite_backend.py │ In-memory + SQLite WAL
292
334
  └─────────────────────────────────────────────────┘
293
335
  ```
294
336
 
295
- Storage uses **MessagePack** for efficient binary encoding of graph properties. Persistence is a single SQLite file with WAL mode for durability.
337
+ The algorithm and search paths bypass the Cypher executor entirely — `db.gds` and `db.search` are Python-method surfaces, not Cypher extensions. Storage uses **MessagePack** for efficient binary encoding of graph properties.
296
338
 
297
339
  ---
298
340
 
@@ -321,9 +363,8 @@ make coverage
321
363
  |---------|-------|--------|
322
364
  | v0.3.8 | Full TCK compliance (3,885/3,885) | **Released** |
323
365
  | v0.3.9 | Performance: LALR parser, property indexes, bulk ingest, SQLite tuning, LIMIT short-circuit | **Released** |
324
- | v0.3.10 | Analytics integration: NetworkX/igraph export, parse/plan cache | Planned |
325
- | v0.4.0 | Native SNA algorithms: PageRank, betweenness, WCC, shortest path via `CALL gf.algo.*` | Planned |
326
- | v1.0 | Production-ready: thread safety, large graph support | Future |
366
+ | v0.3.10 | Analytics integration: NetworkX/igraph export, parse/plan cache, `add_graph_documents()` | **Released** |
367
+ | v0.4.0 | Three-surface API: `db.gds.*` graph algorithms + `db.search.*` hybrid retrieval | **Released** |
327
368
 
328
369
  See [CHANGELOG.md](CHANGELOG.md) for full release history.
329
370