feat(graph): deterministic Louvain community detection (hq-zlph)#31
Merged
Conversation
aegis-1p0 Gap 3. Finish the planned community detection on the existing petgraph Projection API. - graph::louvain: hand-rolled, pure-Rust deterministic Louvain (modularity local-moving phase). Reads the projected directed multigraph as undirected weighted (parallel edges summed, self-loops dropped). Determinism is a hard AC: ascending entity-id visitation, ascending-label candidate evaluation, lowest-label tie-break — same graph always yields the same partition. No C-backed clustering dependency. Returns groups + Newman-Girvan modularity. - tool_project: new algorithm "louvain" (alias "community"). Read-only by default; takes &mut Store (handler ro_handler -> rw_handler) so an opt-in persist:true can write through the store. - persist_communities: writes quipu:memberOfCommunity facts via the store write path (provenance source "algo:louvain"). Bitemporally SUPERSEDES the prior derivation — reconciles by (entity, community-term), retracting changed memberships and asserting new ones, so a current-facts query always returns exactly the latest partition (no stale accumulation, AC 5). Diff rather than retract-all+reassert because the facts table is keyed (e,a,v,tx). - Communities are emergent clustering, NOT an access boundary (AC 6) — documented in the module header, persist fn, and design doc. Adds quipu:memberOfCommunity + community_<k> under the quipu namespace. Tests: two-clique fixture separates deterministically (AC 1/3), persist writes SPARQL-queryable membership + read-only default (AC 2), re-run supersedes prior membership without accumulation (AC 5). Clippy + fmt + tests green on both CI feature sets. Docs: pagerank.md community section, mcp-tools.md reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdgxbhR39MuL7qwHP8vhFT
scbrown
added a commit
that referenced
this pull request
Jul 14, 2026
Louvain community detection (#31), live graph report + quipu_report tool (#32), episode-scoped retraction (#33), and --base-ns/--timestamp CLI flags (#34). Manual release: release-plz's release-pr step is blocked by the repo's "Actions may not create PRs" setting (403); cutting the tag + GitHub release by hand per the established fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VsuPDxSUjMYqHvQyPvSAPW
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.
What (aegis-1p0 Gap 3)
Finishes the planned community detection on quipu's existing petgraph Projection API. New
tool_projectalgorithmlouvain(aliascommunity) that detects modularity-based communities and can persist them as queryable facts.Implementation
graph::louvain— hand-rolled, pure-Rust deterministic Louvain (modularity local-moving phase). The projected directed multigraph is read undirected/weighted (parallel edges summed, self-loops dropped). Determinism is a hard AC: ascending entity-id visitation, ascending-label candidate evaluation, lowest-label tie-break → the same graph always yields the same partition, independent of hash order. No C-backed clustering crate (quipu = zero-unsafe/minimal-dep). Returns groups + Newman–Girvan modularity.tool_projectnow takes&mut Store(handlerro_handler!→rw_handler!); read-only by default,persist:trueopt-in.persist_communities— writesquipu:memberOfCommunityvia the store write path with provenancesource = "algo:louvain". Bitemporally supersedes the prior derivation (AC 5): reconciles by(entity, community-term), retracting changed memberships and asserting new ones, so a current-facts query always returns exactly the latest partition — no stale accumulation. (Diff rather than retract-all+reassert because thefactstable is keyed(e,a,v,tx)— retracting and re-asserting an identical triple in one tx would collide.)group_id; documented in the module header, the persist fn, and the design doc so no consumer builds access control on it.Design provenance
Scope + write-path semantics resolved with dearing (opt-in persist, store write path) and ian-endorsed (AC 5 supersede-on-rerun, AC 6 not-an-access-primitive). The bead's original "persist like quipu:pageRank" was corrected —
tool_projectarms were all read-only; this adds the first write path deliberately and opt-in.Tests (all green on both CI feature sets)
louvain_finds_two_clusters_deterministically— two-clique fixture separates correctly; same graph → identical partition (AC 1/3).louvain_persist_writes_queryable_membership—persist:truewrites SPARQL-queryablequipu:memberOfCommunity; read-only default writes nothing (AC 2).persist_supersedes_prior_membership— re-run with changed partition leaves exactly one active membership per entity (AC 5).cargo fmt --all --check,clippy -D warnings, and full tests pass under--no-default-featuresand--features shacl. No new MCP tool (algorithm param on existingquipu_project), so no tool-count change.Docs:
pagerank.mdcommunity section,mcp-tools.mdreference.Closes hq-zlph. (quipu in hq rig until qp- stands up.)
🤖 Generated with Claude Code