docs: describe the boundary check that actually ships - #27
Merged
Merged
Conversation
PR #26 generalized module-boundary enforcement from :app to every library module. Six documents still described the old, narrower check. This is the follow-up that was deliberately left out of that PR, so the docs are written against proven behaviour rather than intended behaviour. wiki/07 - Finding 8 was 'enforcement stops at :app'. That gap is closed, so the row now states the gap that remains: the check reads Kotlin imports, so a project(':x') line in a build script still couples modules invisibly to it. - Remediation 6 records the half that shipped and the half that did not. - Remediation 3 gains the CancellationException note. A broad catch in safeCall must rethrow it, or a cancelled coroutine is silently converted into a failed Result. - New decision-log entry documents the rule table, why the navigation exception is design rather than a loophole, the per-module escape hatch, and how the check was proven by deliberately breaking it. - Three risks added that were true but unstated: the plug-out job covers 4 of roughly 12 optional modules, mkdocs --strict is not a pull-request check, and main is unprotected. - Finding 3 no longer claims '5 unit tests'. That number was never re-derived from the tree. It now names the two test classes that demonstrably exist. - The dead fifth open question is removed: the CI plug-out job has deleted benchmark/ and baselineprofile/ since PR #23, which answered it. wiki/00, wiki/01, wiki/README.md - Convention plugin count 19 -> 20. - The ':app may import only ...' notes now describe the whole graph. - 00's 'feature-to-feature isolation is unchecked' entry was outright wrong after #26 and is replaced by what is genuinely still unenforced. - 07 is now 20 findings. wiki/08 - Adds the two verification commands for the new task. build-logic/README.md - Documents composetemplate.module.boundary, updates the file tree, and fixes '~48 modules', which has been 47 for several PRs.
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.
The follow-up deliberately left out of #26. That PR generalized module-boundary enforcement from
:appto every library module; six documents still described the narrower check. Docs written against proven behaviour rather than intended behaviour, which is the whole reason they were held back.No code changes. Six files.
wiki/07Finding 8 was the stale one. It read "Module-graph enforcement stops at
:app". That gap is closed, so instead of deleting the row it now states the gap that remains: the check reads Kotlinimportlines, so aproject(":…")line in a build script still couples two modules invisibly to it. The finding keeps its number and its impact tier, because the risk did not disappear — it got smaller and more specific.Remediation 6 records which half shipped and which did not, and adds a constraint discovered the hard way: a build-file check has to reason about dependency direction, not just pattern-match, because a reverse edge into an always-present module is also how a Gradle task-graph cycle gets created.
A new decision-log entry carries the rule table, why the
feature.*.navigation.*exception is existing design rather than a loophole added to keep the build green, the per-module escape hatch, and how the check was proven by deliberately breaking it — including the control case, the two probe lessons, and why the failure report travels in the exception message instead oflogger.error.Remediation 3 gains the
CancellationExceptionnote. A broadcatchinsafeCallmust rethrow it before mapping anything else, or a cancelled coroutine is silently converted into a failedResultand the caller treats teardown as an error. Adding a broad catch without that line makes the code worse, not better.Three risks added (18–20) that were true for a while but unstated:
mkdocs build --strictis not a pull-request check, so a broken link fails after merge, once it is already public;mainis unprotected, and a fast merge can outrun CI entirely — docs: correct stale claims in project context and wiki index #25 was merged about a minute after opening and none of its checks ran.Two corrections rather than additions:
BaseRepositoryTestandTokenAuthenticatorTest, which is the part that supports the finding anyway.benchmark/andbaselineprofile/— is removed. feat: make baseline profile tooling pluggable via composetemplate.perf #23 did exactly that; the question had been answered by the CI file for several PRs while still being asked on the page.Finding 11 picks up the empty-module observation (
feature/home/domainhas abuild.gradle.ktsand no sources), since it is the same question the row already asks. Finding 16 now separates what CI proves — the performance tooling is removable — from what it does not: that a benchmark ever runs.wiki/00,wiki/01,wiki/README.mdConvention plugin count 19 → 20 in all three places it appears.
wiki/07is now 20 findings.wiki/00had an entry under "Opinions the code does not enforce" reading "Feature-to-feature isolation is unchecked. The boundary task inspects:apponly, so one feature importing another compiles happily." That was outright wrong after #26, and wrong in the most misleading direction — telling a reader a guardrail is absent when it will fail their build. Replaced with what is genuinely still unenforced: build-file coupling, removability being proven for only four modules, and the unprotectedmain.wiki/01gains the 44-library-module figure, since that is the set the check covers and it is not the same as the 47-module inventory.wiki/08Adds
:core:data:checkModuleBoundaryand:feature:auth:presentation:checkModuleBoundarynext to the existing app command, plus the escape hatch in the "Removing what you do not need" section. Records thatktlintCheckdoes not triggerpreBuild, so a lint-only run will not surface a violation — a genuine surprise if you are trying to reproduce a red pipeline locally.build-logic/README.mdDocuments
composetemplate.module.boundary, notes thatcomposetemplate.android.libraryapplies it, and updates the file tree (CheckAppModuleBoundaryTask.ktis gone;CheckModuleBoundaryTask.ktandModuleBoundaryPlugin.ktare new).Also fixes
~48 modules, which has been 47 since module discovery landed. Small, but it is the kind of number a reader trusts precisely because nobody would bother to fake it.What is not here
last-updated/ version stamps. Automating them needsfetch-depth: 0inpages.yml, which needs workflow write. Content freshness first.wiki/07items awaiting a decision rather than an edit: reprioritizing finding 4 (pick one serialization stack), reframing finding 1, and raising finding 9.Verification
CI on a docs-only change produces a cache-heavy green run that verifies nothing about the documents themselves. The claim worth checking is that the rule table, task names, report paths and the escape-hatch snippet match
ModuleBoundaryPlugin.ktandCheckModuleBoundaryTask.ktas merged — every one of them was copied from the source onmain, not from the PR description of #26.mkdocs build --strictis not a pull-request check (finding 19), so the internal links added here — the#baseline-decision-loganchor in particular — are unverified until the site rebuilds after merge.