feat(architecture): add Humans.Interfaces project as marker-only seam#1120
feat(architecture): add Humans.Interfaces project as marker-only seam#1120peterdrier wants to merge 1 commit into
Conversation
Phase 1 of the per-section project split (nobodies-collective#866): new lowest-level src/Humans.Interfaces project with zero ProjectReferences, holding the system marker interfaces (IApplicationService, IOrchestrator, IInvalidator, IFanout, IRepository) and architecture attributes (Grandfathered, DontFix, SurfaceBudget). Namespaces are preserved exactly (namespace != assembly), so no using changes and the Humans.Analyzers full-name constants keep resolving. Only non-mechanical change: two test reflection anchors that used typeof(IApplicationService).Assembly to mean "the Humans.Application assembly" are re-anchored to types that stay in that assembly. Left behind on purpose: IRecurringJob (has a member, not a pure marker) and ExpiresOnAttribute (lives in Humans.Domain, untouched in phase 1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The preview deployment for humans-qa is ready. 🟢 Open Preview | Open Build Logs | Open Application Logs Last updated at: 2026-07-15 14:47:56 CET |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 996dcd4cf2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\Humans.Domain\Humans.Domain.csproj" /> | ||
| <ProjectReference Include="..\Humans.Interfaces\Humans.Interfaces.csproj" /> |
There was a problem hiding this comment.
Copy Humans.Interfaces.csproj in the Docker restore layer
When building the Docker image, the restore layer copies the existing Domain/Application/Infrastructure/Web project files (Dockerfile:7-10) and runs dotnet restore src/Humans.Web/Humans.Web.csproj before COPY src/ src/; this new ProjectReference points to src/Humans.Interfaces/Humans.Interfaces.csproj, which is not present in that layer, so Docker restores fail with a missing project file before publish can run. Add a matching COPY for the new project before the restore step.
Useful? React with 👍 / 👎.
PR Surface ReportCompared Summary: 13 changed file(s) | EF migrations: 0/1 Reforge Surface Score
Section DeltasNo section score changes. Rule DeltasNo rule score changes. Interface SurfaceNo new interfaces or interface methods. Diff Size
New Files
|
Summary
Phase 1 of the per-section project split (nobodies-collective#866, G5): create the new lowest-level
src/Humans.Interfacesproject and move the system markers + architecture attributes into it. The point of this PR is the seam — it is deliberately boringly small.Moved (8 files,
git mv, 100% similarity):IApplicationService,IOrchestrator,IInvalidator,IFanout(Humans.Application.Interfaces)IRepository(Humans.Application.Interfaces.Repositories)GrandfatheredAttribute,DontFixAttribute,SurfaceBudgetAttribute(Humans.Application.Architecture)Wiring:
Humans.Interfaces.csprojhas zero ProjectReferences and zero PackageReferences (it inheritssrc/Directory.Build.props, so it gets the Humans.Analyzers analyzer reference and MinVer like every other src project). Added toHumans.slnx;Humans.Applicationgains the one ProjectReference. Domain untouched.Namespaces preserved exactly — namespace ≠ assembly. Zero
usingchanges anywhere, and allGetTypeByMetadataNamefull-name constants in Humans.Analyzers keep resolving unchanged (verified:Humans.Application.Interfaces.IApplicationService,…Repositories.IRepository,…IOrchestrator,…IInvalidator,…Architecture.GrandfatheredAttribute,…SurfaceBudgetAttribute).The one deviation from "zero call-site changes" (tests only)
Two tests used
typeof(IApplicationService).Assemblyas a reflection anchor meaning "the Humans.Application assembly", which now resolves to the new marker assembly:ServiceBoundaryArchitectureTests.ApplicationInterfaceTypes()— re-anchored totypeof(IUserRepository).Assembly. Behavior-identical: every consumer already excluded the marker types explicitly (t != typeof(IApplicationService)/!= typeof(IRepository)/!= typeof(IOrchestrator)). Caught by theApplicationServiceEntityReadReturnsratchet failing on stale baseline entries.DependencyCycleResolutionTests.NoCircularConstructorDependencies_AcrossApplicationServices— re-anchored totypeof(UserService).Assembly. This one would have silently passed while scanning zero Application services, so leaving it was not an option.No other assembly-keyed anchors exist: swept
src/+tests/fortypeof(<moved type>)reflection usage,tests/BannedSymbols.txt, andInternalsVisibleTodeclarations — nothing else references the moved types by assembly.Left behind on purpose
IRecurringJob— declaresExecuteAsync, so not a pure member-less marker ("when in doubt, leave behind").ExpiresOnAttribute— lives inHumans.Domain.Architecture; Domain is untouched in phase 1.Humans.Interfaces.*— only after the Show camp EE allocation total on Members card #858 stack merges (rewrites usings everywhere).Verification
dotnet build Humans.slnx -v quiet— 0 errors, 95 warnings (all pre-existing grandfathered HUM ratchets)dotnet test Humans.slnx -v quiet— all suites green (incl. Docker integration tests): 271+222+365+3865+116 passeddotnet format --verify-no-changes— cleanParallel to (not stacked on) the #858 DbContext-split PR stack — zero file overlap.
🤖 Generated with Claude Code