100%

GDS activation as hygiene signals

Goal

Turn the de-noised CALLS graph into reviewer signals by activating the GDS algorithms Community edition already ships (WCC / Bridges / SCC / articulation / Leiden) plus a custom Cypher phase-order cycle check. Each signal is COMPUTED and materialized on :Symbol here; surfacing them as intel-query.sh subcommands is the sibling query-primitives section’s job.

Dependency

  • Consumes the de-noised CALLS graph delivered by calls-resolution-precision (s-1209f1e9): GDS projections run over CALLS edges with zero non-callable-kind edges and arity-recovered homonyms.
  • Declared as hint_needs: in route state. s-1209f1e9 is route-order section 2, this is section 4 — a valid forward edge per linear-DAG INV-19.
  • Running these algorithms over the pre-de-noise graph re-introduces the extend-collision and homonym false edges as false hygiene signals.

Compute-vs-wrap boundary (with query-primitives s-9fb83bc7)

  • gds-activation (this section) COMPUTES the GDS signals and writes each as a property on :Symbol nodes (the materialized graph-enrichment surface).
  • query-primitives (s-9fb83bc7, w-ae23d73a) WRAPS those materialized signals as intel-query.sh dead-code / intel-query.sh layering-check subcommands and feeds them into the phase-2.5-graph-recon pre-pass.
  • query-primitives’ dead-code and layering-check primitives consume THIS section’s materialized GDS signals: their unblock-point is s-4e62453e (this section), not the raw de-noised walking-skeleton at s-1209f1e9. The query-primitives body (s-9fb83bc7) reflects this — its Implementation Sketch and w-ae23d73a reference s-4e62453e as the predecessor that materializes the signals they wrap.
  • This section’s success criterion (sc-89902b3f) asserts pytest + live-graph property materialization, NOT an intel-query.sh layering-check / dead-code command-probe — those subcommands are query-primitives deliverables that do not exist at this section’s close.

Reference-delta — gds_enrich.py must be EXTENDED

  • intel_repo/neo4j/gds_enrich.py runs ONLY PageRank / betweenness / Leiden under GDS 2.13.x.
  • The WCC / Bridges / SCC / articulation projections named in the work items are valid GDS-CE algorithms but are NOT yet wired there.
  • This section EXTENDS gds_enrich.py with the new per-algorithm projections and property writes; it does not assume they already exist.
  • Verify the deployed GDS-CE algorithm catalogue at implementation start before committing each projection.

Implementation Sketch

Materialize a Symbol.crate property via the existing path classifier, then project per-algorithm GDS graphs over a test/doc-filtered node set: WCC from a defined root-set (dead code), Bridges/SCC across the crate property (layering), articulation/betweenness (blast radius), Leiden spanning crates (scattered knowledge), and a custom-Cypher SCC-based phase-order cycle check. Each maps to a reviewer signal and writes a property onto :Symbol.

Pre-work decision 1 — test/doc projection filter (load-bearing)

Roughly half the ori symbol corpus is test/doc-path (50.5% at last graph sync — recompute by bucketing every :Symbol {repo: 'ori'} node through intel_repo/neo4j/path_class.py:_is_test_or_doc_path (the same predicate metrics.py Score B + hotspot apply) and dividing the test/doc-classified count by the total; re-confirm against the live graph at implementation start). An unfiltered GDS projection drowns every reviewer signal in test-fixture noise. Filter the projection node set with the existing intel_repo/neo4j/path_class.py:_is_test_or_doc_path predicate (already used by metrics.py Score B + hotspot) BEFORE WCC (dead-code), Leiden (scattered-knowledge), and articulation (blast-radius). Apply a Leiden post-filter that drops communities dominated by test symbols so scattered-knowledge surfaces production clusters.

Pre-work decision 2 — WCC dead-code root-set (load-bearing)

  • WCC-from-roots dead-code detection requires the root set to be @main entry points plus pub-exported entry points.
  • Without that explicit root-set, symbols reachable only from un-chosen roots become false-positive dead code.
  • Define the root-set as @main + pub function entry points; the WCC component holding NO root symbol is the dead-code candidate set.

Pre-work decision 3 — Symbol.crate must use the robust classifier (not a path split)

Deriving Symbol.crate from a hardcoded split(file,'/')[1] is layout-sensitive: a leading prefix or a moved crate root silently mis-buckets every symbol and corrupts Bridges/SCC layering detection. Use path_class.py with a defined crate-bucket allowlist; leaf-classify or EXCLUDE non-layer buckets (test/doc/generated) before the layering projection runs.

Pre-work decision 4 — phase-order ordering uses gds.dag.topologicalSort; cycle detection stays custom Cypher

  • GDS-CE 2.13.x DOES ship a native topological-sort procedure — gds.dag.topologicalSort.stream (alongside gds.dag.longestPath.stream), confirmed in the deployed catalogue via CALL gds.list().
  • gds.dag.topologicalSort yields a topological ORDERING over a presumed-acyclic graph; it is not itself a cycle detector. Use it to produce the crate-layer ordering signal.
  • Phase-order CYCLE detection (the reviewer signal that flags a layering back-edge) still requires a custom Cypher SCC/path check over the crate-layer DAG — a topo-sort does not report the offending back-edge.
  • Confirm the deployed GDS-CE catalogue at implementation start before committing each procedure.

Work Items

Every work item below authors its slice of the pytest coverage in intel_repo/tests/test_gds_enrich_unit.py (success criterion sc-89902b3f) — extending the existing module test, NOT a new file under neo4j/ (the GDS tests live in intel_repo/tests/) — BEFORE the projection/Cypher code it tests — tests precede code per the TDD discipline, so no work item closes implementation-only. The shared coverage spans projection lifecycle (project -> run -> write -> drop), the test/doc projection filter, the WCC root-set, and the per-algorithm candidate ceilings; each item contributes the assertions for the signal it materializes. A dedicated test-authoring work_item is the canonical WBS shape for sc-89902b3f — minting that route node is a plan-engine operation, surfaced in the editor handoff.

  • Materialize a Symbol.crate property via path_class.py with a crate-bucket allowlist (NOT split(file,'/')[1]), excluding non-layer buckets, so GDS can project a layer dimension robustly under layout changes.
  • WCC-from-roots (@main + pub entry-point root-set) over the test/doc-filtered de-noised CALLS graph -> dead-code candidates; root-holding components are live, root-less components are candidates.
  • Bridges / SCC-across-the-crate-property over the layer-bucketed projection -> layering-violation detection.
  • Blast-radius ranking over the test/doc-filtered projection, written as a :Symbol blast-radius property. betweenness is ALREADY computed by gds_enrich.py (per the Reference-delta above — it already runs PageRank / betweenness / Leiden), so it needs only a re-run over the filtered/de-noised projection, NOT fresh wiring; articulation-points is the genuinely new GDS-CE projection to add here.
  • Two distinct mechanisms (per Pre-work decision 4), each writing its own reviewer property onto :Symbol: (a) Leiden-spanning-crates with a test-community post-filter -> scattered-knowledge (a GDS-CE projection); (b) phase-order validation — gds.dag.topologicalSort (native GDS-CE, available now) produces the crate-layer ordering, with a custom SCC/path Cypher check over the crate-layer DAG for the cycle detection topo-sort does not itself report. These two mechanisms are tracked under one work-item node here; splitting them into separate route nodes is a route-substrate change owned by the plan engine (surfaced in the editor handoff).

References

intel_repo/neo4j/gds_enrich.py (EXTEND with WCC/Bridges/SCC/articulation projections + property writes); intel_repo/neo4j/path_class.py (_is_test_or_doc_path projection filter + crate-bucket classifier); intel_repo/neo4j/metrics.py (Score B / hotspot filter precedent); .claude/rules/missions.md (per-crate layering constraints); query-primitives s-9fb83bc7 (downstream query-surface wrapper).