Repository navigation
refactor(arch): finish package-by-module — contracts by folder, no marks or claim lists - #1099
Merged
Merged
Conversation
…oduleContract]
Every module's contract now sits in Modules/<Owner>/Contracts, so the mark,
its attribute, the mark branch of RealModuleLedger.DeriveContracts and the
mark-plus-folder overlap error go. A contract is a top-level type in a
Cluckwork.{Domain,Application}.Modules.<Owner>.Contracts namespace;
NamespaceFolderAgreementTests keeps that namespace equal to its folder. The
attribute's Implementations and Types properties go with it (next commit
removes their readers).
Refs #1087
No owner used either after the module moves: repositories read their tables as their module's own code (S9), and Access's identity ports sit in Access's namespace (S8). The ledger model, its validation, the analyzer's Types reading, the peer walk's claimed-type roots, the compatibility scanner's implementation allowance and the fixture tests of those features go. Refs #1087
…global usings Nothing outside Domain/Common/Architecture uses that namespace now that the marks are gone; the rules files sit in it and need no using. Refs #1087
src/AGENTS.md now says a contract is the Modules/<Owner>/Contracts folder, owner rows claim fixed roots, registrations live under Api/Modules/<Owner>, and drops the type-claim and Implementations rules. Amendments to #514, #849, #850, #859 and #1023 record what changed. Two stale code comments (IFlockModule, ModuleMap) follow. Refs #1087
mforce
force-pushed
the
refactor/1087-cleanup
branch
from
October 6, 2026 02:39
bc4e350 to
5dcafde
Compare
This was referenced Oct 6, 2026
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.
Refs #1087
S10 of the package-by-module design: the cleanup. Every module now lives in
Modules/<Owner>/with its contract inContracts/, so the transition mechanisms go. Only how the policy is enforced changes. The policy itself, and the product, do not. Proofs compare this head with the basefb3a9cd3(#1097, S9); the long proofs are being added below as they finish. S11 (#1098, the diagram) runs in parallel and reads the edge cells, which this PR keeps; whichever merges second rebases.Review order
[ModuleContract], its attribute, the mark branch ofRealModuleLedger.DeriveContractsand the mark-plus-folder overlap error are deleted. A contract is a top-level type inCluckwork.{Domain,Application}.Modules.<Owner>.Contracts;NamespaceFolderAgreementTestskeeps that namespace equal to its folder. The contract-derivation fixture loses its marked type and the overlap test.ImplementationsandTypesare removed fromModuleOwnerAttributeandOwnerDefinition, along with their validation, the analyzer'sTypesreading, the peer walk's claimed-type roots, the compatibility scanner's "declared implementation" allowance, and the fixture tests of those features. No owner used either: S9 made repositories module code, and S8 moved Access's identity ports into Access's namespace.global using Cluckwork.Domain.Common.Architecture;is deleted from both Application and Domain. Nothing outsideDomain/Common/Architectureuses it (checked by grep, since IDE0005 is not enforced), and the rules files sit in that namespace.src/AGENTS.mdnow says the contract is theContracts/folder, owner rows claim fixed roots, and registrations live underApi/Modules/<Owner>/; the type-claim andImplementationsrules are removed. Amendments are appended to Modular-monolith architecture design + implementation plan (from PR #423) #514, [C] #514 slice 7: Finance pilot — first module behind a contract #849, [C] #514 slice 8: close or date every compatibility exception #850, [C] #514 slice 17: assembly split — conditional on Track A/B evidence #859 and test(arch): guard module-to-module calls against non-contract types #1023. Two stale code comments (IFlockModule,ModuleMap) are fixed.graphify update .is left out of this PR at the owner's request: AGENTS.md says not to bundle graphify regeneration into code PRs.The five scoped guards
S0 widened these five guards for the transition. None of them names an old root any more, and each root it still walks holds live code, so narrowing any of them would make it looser:
SeamSurfaceRealAssemblyTestsModules+Common; Application has no other namespaceAdapterRoots/PersistenceForbiddenNamespacesApi.Endpoints,Api.Modules(+ Cli, Jobs, seeders)Api/Endpoints/ClientErrorsstays there by designInsightsReadOnlyTestsTrackedMutationReadTestsRepositories/**andModules/<Owner>/Repositories/**Infrastructure/Repositoriesstill holds Platform code (AuditWriter,LiteralSearch,ReferenceMarkers)ServingGuardCoverageTestsApi.HostingandApi.ModulesServingBootGuardsand the composition files stay in HostingA stray old-root namespace fails as unowned through the owner rows, which claim only the fixed roots. The mutation below proves it.
Checks at push time
dotnet build Cluckwork.slnArchitecture+TenantBypass+Documentation+ImagePintypespeer rows, 5Implementationscompatibility)SchemaDocsTests,ServingGuardCoverageTests,TrackedMutationReadTests; Domain.TestsProofs: nothing got looser (base
fb3a9cd3vs headbc4e3501; the head is now5dcafde8, the same tree without the dropped graphify commit, so the proofs still apply)No file moved in this slice, so base and head reports compare directly. File and line positions are excluded.
Contracts/folders onlyTenantBypass/)coupling-matrix.mdCouplingMatrixRealTreeTestsgreen)migrations has-pending-model-changesMigrations/change. Control:HasMaxLength(ExpenseCategory.MaxNameLength + 1)makes the same command exit 1tools/schema-docs/generate.sh --checkMutations (spare worktree at the head; each case reset, built and run against the
Architecture+TenantBypassfilter; a case the analyzer stops is rebuilt with analyzers off so the guards still run)Contracts/UpdateCustomerCommand.cs(file and namespace) back toCustomers/UpdateCustomer/AdapterReachRealTreeTests(CustomerEndpointsreaches a non-contract type),CouplingMatrixRealTreeTestsUpdateCustomerCommand: a type moved out ofContracts/loses contract status.Contractsnamespace keptNamespaceFolderAgreementTestsCreateExpenseHandler.csreferences Commerce'sCustomer(no Finance → Commerce cell)CW1001undeclared cross-owner edge Finance → CommerceModuleLedgerRealTreeTests.RealSourceTree_EveryCrossOwnerEdgeIsLedgered,CouplingMatrixRealTreeTests(2)Cluckwork.Application.Features.Stray(a record underApplication/Features/Stray/)CW1003unowned namespaceCluckwork.Application.Features.StrayModuleLedgerRealTreeTests("unowned namespace 'Cluckwork.Application.Features.Stray' declared in src/Cluckwork.Application/Features/Stray/StrayProbe.cs"),CouplingMatrixRealTreeTests