Skip to content

Header graph → verified DAG: untangle the dht endpoint cluster (consolidation precondition 3) - #37

Merged
ptesavol merged 1 commit into
mainfrom
refactor/dht-include-dag
Jul 4, 2026
Merged

ptesavol merged 1 commit into
mainfrom
refactor/dht-include-dag

Conversation

@ptesavol

@ptesavol ptesavol commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Closes consolidation precondition 3 from the Phase 2.6 decision memo — and it turned out to be much smaller than the memo feared.

The analysis

The memo's wording ("dht intra-package include cycles, connection/endpoint cluster — untangle or use coarse per-cluster partitions") dated from Phase 2.4. A monorepo-wide dependency analysis of all seven packages' headers, counting two edge kinds:

  • #include edges between same-package headers, and
  • forward-declaration edges (class X; of a type defined in a sibling header) — these are what break cycles textually, but a forward-declared entity owned by another partition still forces a cyclic import once headers map onto module partitions, so they count as real edges for the consolidation.

Result: the raw include graphs were already acyclic everywhere, and exactly one semantic cycle exists in the entire monorepo — the 6-header dht endpoint state-machine cluster: EndpointStateInterface forward-declared Endpoint, held an Endpoint&, and had its member definitions at the bottom of Endpoint.hpp; the four state classes include the interface; Endpoint includes the states.

The fix

EndpointStateInterface becomes a pure abstract interface (5 virtual methods, no members). Endpoint implements it privately and passes *this to the state objects. The state classes are untouched — they always called through an EndpointStateInterface&. The old forwarder's bodies were 1:1 calls into Endpoint methods that are now simply the overrides themselves (the redundant recursive-mutex lock the old handleDisconnect forwarder took first is subsumed by the lock the target method takes). The inline definitions and the friend disappear.

Header graph after: states → interface ← Endpoint — acyclic. Every package's header graph is now a verified DAG, which means consolidation can pick any partition granularity, including per-header.

Enforcement

New check-include-dag.py (stdlib-only) validates the DAG property — both edge kinds — for every package; lint.sh runs it, so a newly introduced cycle fails CI with the offending headers listed instead of surfacing months later as an unbuildable partition layout.

Verification

  • check-include-dag.py: all 8 packages acyclic
  • streamr-dht suite: 81/81 (Release)
  • trackerless-network suites: green (Release)
  • MODERNIZATION.md memo updated: precondition 3 RESOLVED — consolidation is now gated only by clangd purview-lint coverage (precondition 2)

🤖 Generated with Claude Code

Consolidation precondition 3 (MODERNIZATION.md Phase 2.6 memo) asked for
the dht include cycles to become a partition DAG. A monorepo-wide
analysis — include edges plus forward-declaration edges, which are what
break cycles textually but still force cyclic imports once headers map
onto module partitions — found exactly one cycle across all seven
packages: the 6-header dht endpoint state-machine cluster
(EndpointStateInterface held Endpoint& with its member definitions at
the bottom of Endpoint.hpp).

- EndpointStateInterface is now a pure abstract interface; Endpoint
  implements it (privately) and passes itself to the state objects. The
  state classes are unchanged. No behavioral change: the interface
  methods forwarded 1:1 to the Endpoint methods that are now their
  overrides (the extra recursive-mutex lock the old handleDisconnect
  forwarder took is subsumed by the lock the target method takes).
- check-include-dag.py verifies the DAG property (both edge kinds) for
  every package; lint.sh runs it, so a new cycle fails CI with the
  offending headers listed.
- MODERNIZATION.md: precondition 3 marked RESOLVED — consolidation is
  now gated only by clangd purview-lint coverage.

Verified: streamr-dht suite 81/81, trackerless-network suites green
(Release); checker reports all 8 packages acyclic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@ptesavol
ptesavol merged commit d78e03d into main Jul 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant