feat(celery Wave 6 #33 chunk 2): cross-backend keyword + traversal + chunk 1 amend#1741
Merged
Conversation
…pls + chunk 1 amend (drop vector-recall) Per architect Option A ruling msg=54eac595 — chunk 2 is narrowed to `query_entities_by_keyword` + `expand_neighbors_n_hops` across all three backends. `query_entities_by_vector` is dropped: the Wave 4 lineage schema has no entity-vector column, and adding either an entity vector index or a Qdrant cross-concern coupling violates the simple-stable-directive separation of concerns. Wave 7 may re-introduce vector recall via a separate `LightRAGQueryService` if real evidence surfaces. `aperag/indexing/graph.py`: * Drop `query_entities_by_vector` Protocol method declaration (was in chunk 1) + replace with explicit dropped-by-design comment pointing at the architect ruling. * `InMemoryLineageGraphStore` ships REAL implementations of the two remaining methods (substring match + BFS frontier traversal) so unit tests can exercise the canonical semantics without standing up a database. `aperag/indexing/graph_storage/postgres.py`: * `query_entities_by_keyword`: `WHERE name ILIKE '%query%'` ordered by name, limit `top_k`. ILIKE is the canonical case-insensitive substring idiom on Postgres. * `expand_neighbors_n_hops`: BFS-style frontier expansion. Per hop: fetch relations where `source IN $names OR target IN $names`, collect unseen endpoints as next frontier, fetch their entity rows. Bounded by `hops`. Single connection across all hops. `aperag/indexing/graph_storage/neo4j.py`: * `query_entities_by_keyword`: `MATCH (n:aperag_LineageEntity ...)` + `WHERE toLower(n.name) CONTAINS toLower($query)` + `ORDER BY n.name LIMIT $top_k`. Cypher 5.x has no built-in case-insensitive CONTAINS, so this is the canonical idiom. * `expand_neighbors_n_hops`: Same BFS pattern as Postgres but expressed as two Cypher MATCH queries per hop (entities by name IN list, relations by source/target IN list). Relations are stored as labelled nodes (not edges) per the Wave 4 schema, so traversal is JOIN-style not Cypher-pattern-style. `aperag/indexing/graph_storage/nebula.py`: * `query_entities_by_keyword`: enumerate all entity VIDs via the existing `_list_all_entity_vids` helper, read each lineage by VID, filter substring-match in Python, sort by name, return top_k. Nebula has no JSON / text-search index on tag string properties so this is necessarily a scan — acceptable per simple-stable directive (no per-collection text-index infra to manage). * `expand_neighbors_n_hops`: same scan-and-filter pattern as `find_relation_keys_with_lineage`. Per hop, scan all relation VIDs and filter by source/target ∈ current frontier. Read each matching relation + its endpoints. Wrapped in `asyncio.to_thread` since Nebula's Python driver is sync. `tests/unit_test/indexing/test_lineage_query_protocol.py`: replaces the chunk-1 Protocol-stub tests with real semantic tests against `InMemoryLineageGraphStore` (10 total): * Protocol surface declares 2 read methods (vector-recall removed). * Signature contract: kw-only args + `hops=1` default. * `query_entities_by_keyword`: substring matches (Alice / Bob / Carol fixture) + `top_k <= 0` and empty/whitespace query return `[]`. * `expand_neighbors_n_hops`: 1-hop / 2-hop / 0-hop / empty seeds / unknown seed cases. Production-readiness 三类 (chunk 2): - must-be-real: real keyword + real BFS traversal across 3 production backends; in-memory store ships matching semantics. - may-be-gated: vector recall NOT shipped (per architect Option A); Protocol surface intentionally narrowed. - fully-resolves: §K.11.11 chunk 2 narrowed acceptance + chunk 1 amend rolled into same commit per architect msg=54eac595. Tests + local gates: * 169/169 indexing unit tests pass (10 query-protocol + 159 existing). * ruff check + format clean. chunk 3 (caller migration: 5 files in retrieval/pipeline.py + knowledge_graph/service.py + graph_curation/* + legacy graphindex package hard-cut delete + grep-zero verify) lands separately. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y_vector + add Pattern 3 Per architect Option A ruling msg=54eac595, fold spec amend into Bryce's chunk 2 PR #1741 (per "由 architect 在 Bryce chunk 2 PR push 后 同 chunk 2 fold 进 spec amend (single PR-A continuation)"). Three §K.11 sub-section edits: 1. §K.11.4 row #33 must-be-real layer: - Removed "vector-recall" from query layer scope - Added explicit "Graph entity vector recall NOT in Wave 6 scope — deferred to Wave 7+ if real evidence" with link to ruling - Cited reason: lineage schema 没承担 entity vector storage; inline coupling 违反 simple-stable directive #3 2. §K.11.5 pre-check pattern lock (renamed from "双 pattern" to "三 pattern"): - Added Pattern 3 (state binding — Protocol method reads from state X) - Pattern 3 trigger: "spec acceptance lock form 'Protocol method reads from state X' must grep-verify state X schema 现存在" - Documented #33 chunk 1 retrospective miss as lesson - Forward template: 4 sub-options when state X schema absent (in-chunk add / prior chunk add / separate service taking state dep / defer to next Wave) 3. §K.11.11 PR-A 3-chunk decomposition: - Added Status column (chunk 1 ✅ MERGED `20b9071b` / chunk 2 🔄 PR #1741 / chunk 3 ⏳ post-chunk-2) - Added "Chunk 1 → chunk 2 amend note" explicit subsection citing architect ruling msg=54eac595 + Pattern 3 sediment - Updated PR-A acceptance items reference: §K.10 (1-5) + amended #33 must-be-real per §K.11.4 Companion memory sediment in `feedback_spec_lock_grep_verify_caller.md` (Pattern 3 added) — keeps spec ↔ memory feedback aligned per `feedback_announce_equals_landed.md` narrative-truth invariant. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wave 6 PR-A "graphindex elimination" — chunk 2 of 3 per §K.11.11 + architect Option A ruling msg=54eac595.
Scope (narrowed per architect ruling):
query_entities_by_keyword+expand_neighbors_n_hopson Postgres, Neo4j, Nebula backends.query_entities_by_vectorProtocol method (was in chunk 1) — Wave 4 lineage schema has no entity-vector column. Wave 7+ may re-introduce via separateLightRAGQueryService.InMemoryLineageGraphStoreships matching semantics for unit tests.Out of scope (chunk 3)
retrieval/pipeline.py+knowledge_graph/service.py+graph_curation/*aperag/domains/knowledge_graph/graphindex/package hard-cut delete + legacy tests delete + grep-zero verifyTest plan
INliststoLower(...) CONTAINS toLower(...)+ Cyphername IN $namestraversaltop_k <= 0, empty seeds, unknown seed, 0-hop, 2-hop, multi-hop expansion🤖 Generated with Claude Code