Skip to content

Enforce module boundaries: Modulith verification + ArchUnit for plugin isolation - #77

Merged
arefbehboudi merged 2 commits into
ClawRunr:mainfrom
MarcosLM11:feature/enforce-module-boundaries
Aug 4, 2026
Merged

Enforce module boundaries: Modulith verification + ArchUnit for plugin isolation#77
arefbehboudi merged 2 commits into
ClawRunr:mainfrom
MarcosLM11:feature/enforce-module-boundaries

Conversation

@MarcosLM11

Copy link
Copy Markdown
Contributor

Summary

  • Adds spring-modulith-starter-test and archunit-junit5 as testImplementation in app/build.gradle (ArchUnit pinned to 1.4.2, the first release supporting Java 25 class files, matching this project's toolchain).
  • Adds ModularityTests running ApplicationModules.of(JavaClawApplication.class).verify() to catch cycles between top-level modules.
  • Adds ModuleBoundaryArchTest with ArchUnit rules covering:
    • Channel plugins independent of each other (telegramdiscord, generalized to any channels.* slice)
    • Tool plugins independent of each other (braveplaywright, generalized to any tools.* slice)
    • LLM providers independent of each other (openaianthropic, generalized to all providers)
    • Providers and plugins don't depend on each other
    • Core (agent, tasks, configuration, files) doesn't depend on any plugin or provider

Test-scope only, no production code touched.

Resolves #76

Add test-scope guardrails so plugins/telegram, plugins/discord,
plugins/brave, plugins/playwright, providers/openai and
providers/anthropic (and siblings) can't accidentally depend on each
other, and core stays free of plugin/provider dependencies:

- ApplicationModules.of(JavaClawApplication.class).verify() catches
  cycles between top-level modules.
- An ArchUnit test enforces channel-plugin, tool-plugin and
  LLM-provider sibling independence, provider/plugin separation, and
  core independence from plugins and providers.
@arefbehboudi
arefbehboudi self-requested a review August 3, 2026 07:34
Comment thread app/src/test/java/ai/javaclaw/ModuleBoundaryArchTest.java
Comment thread app/src/test/java/ai/javaclaw/ModuleBoundaryArchTest.java
Anchor package patterns to the root package so they can't accidentally
match unrelated packages sharing a segment name, and match plugin/provider
groups by package structure instead of enumerating each implementation,
so new plugins are covered automatically without editing this test.

Naively matching whole plugin packages (e.g. "ai.javaclaw.channels..")
briefly flagged TaskHandler for depending on the shared Channel/
ChannelRegistry abstractions that live in that same root package. Scoped
the pattern to plugin subpackages only (ai.javaclaw.channels.*..) so
shared interfaces stay reachable from core while plugin implementations
remain isolated.
@MarcosLM11

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the review, @arefbehboudi! I've pushed a fix addressing both comments:

  • Anchored the package patterns to the root package so they can't accidentally match unrelated packages sharing a segment name.
  • Switched plugin/provider matching to package-structure based patterns instead of enumerating each implementation, so new plugins/providers get covered automatically.

Also worth flagging: widening the match initially surfaced a real (minor) boundary issue where TaskHandler was matched against the plugin packages, since the shared Channel/ChannelRegistry abstractions live in the same root package as the plugin implementations. Scoped the pattern to subpackages only (channels.*..) to fix that without touching TaskHandler.

Full test suite passes. Whenever you have a moment, feel free to take another look — no rush!

@MarcosLM11
MarcosLM11 requested a review from arefbehboudi August 4, 2026 08:48
@arefbehboudi

Copy link
Copy Markdown
Collaborator

@MarcosLM11 Thank you, Nice Job!!

@arefbehboudi
arefbehboudi merged commit 2d6c8f9 into ClawRunr:main Aug 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task] Enforce module boundaries: Modulith verification + ArchUnit for plugin isolation

2 participants