HAS_VARIANT extraction (declaration-derived) + enum-variants primitive
Goal
Build the HAS_VARIANT edge from sum-type declaration ownership and wire the enum-variants primitive that reads it — closing the forward-handoff from query-primitives (s-9fb83bc7).
Implementation Sketch
- Variants are not first-class :Symbol nodes today and construction surfaces as a CALLS onto the PARENT sum_type with no variant endpoint, so HAS_VARIANT is unbuildable from CALLS and CALLS-usage would miss never-constructed variants.
- Build it from DECLARATION data: the extractor already maps Rust
enum_item->sum_typeatintel_repo/neo4j/extract_symbols.py:63; the declaration-symbol MERGE batch is at:600-620. - Emit each variant as a declared node from the sum-type’s declaration, then MERGE
HAS_VARIANT(sum_type -> variant) via the generic edge helper inintel_repo/neo4j/import_code_graph.pyalongside the existing DECLARES MERGE (:619). - The CONSUMER is read-only:
intel_repo/neo4j/insights.py:431build_hygiene_reconrecords enum-variants as intentionally ABSENT (‘requires a new HAS_VARIANT extraction edge’); add an enum-variants primitive there that READS HAS_VARIANT (insights.py does NOT construct the edge — construction in the query layer would be phase-bleeding).
Spec References
- HAS_VARIANT must derive from sum-type DECLARATION ownership, never from CALLS-usage (the originating-section TPR finding).
- Extractor declaration mapping:
extract_symbols.py:63. - Read-only consumer contract:
insights.pybuild_hygiene_recon.
Work Items
- In the extraction/import path, emit each enum variant as a declared symbol/node from the sum-type DECLARATION data (the
enum_itemdeclaration the extractor sees), then MERGEHAS_VARIANT(sum_type -> variant) from that declaration ownership — NOT from CALLS-usage tracing. Then consume it as the read-only enum-variants query primitive in insights.py. Pinned by flipping the test_query_graph_hygiene.py absent-assertion.
Test Coverage
- L12 Production entry point — COVERED: the pytest flips
test_query_graph_hygiene.py:test_build_hygiene_recon_batches_ready_primitives_no_enum_variants(the"enum_variants" not in result["primitives"]absent-assertion at ~line 187) to assert the edge present + the enum-variants primitive returns the documented shape against the seeded live-graph fixture. L1..L11 N/A: Python/Neo4j extraction-and-query change, no Ori compiler pipeline layer applies; intel_repo pytest is the gate. Test-first: the failing assertion frames the slice before the extraction edge lands.