The clean-architecture layout did not build with two of our own features - #254
Merged
Conversation
Found by qorpe/coexist on 2026-09-09, generating that layout as the first adopter to want it. Both breaks have the same shape: the template puts feature-conditional CODE in Domain and Application, but only the Api csproj carried the feature-conditional package references. ## IAuditLogged moves to Goldpath.Abstractions Order.AuditTrail.cs lands in Domain and needs IAuditLogged, which lived in Goldpath.AuditTrail — a package that pulls ASP.NET Core, EF Core and Goldpath.Data. Referencing that from Domain inverts the dependency direction the layout exists to teach, so the fix is not the reference. Its five siblings — IAuditedEntity, ISoftDeletable, IMultiTenant, IIntegrationEvent, GoldpathPersonalData — are all already in Goldpath.Abstractions. The bare marker belongs there too, and both packages declare it in namespace Goldpath, so the move is source-compatible: adopters recompile and change nothing. A TypeForwardedTo was written first and withdrawn. PublicApiAnalyzers cannot reconcile a forwarded type: it reported RS0016 (not part of the declared public API) and RS0017 (declared but could not be found) for the same symbol in the same build. On a pre-1.0 preview train the recompile is cheaper honesty than a suppression that outlives its reason. ## The Application project gets the behaviours package it already uses CreateOrder.cs carries [Mediant.Behaviors.Attributes.Idempotent] under UseIdempotency and lands in Application, and NO template csproj referenced Mediant.Behaviors at all — in vertical-slice the file lands in Api and reaches it transitively through Goldpath.Idempotency. Central package management makes the fix two lines: the conditional reference and its PackageVersion. Proven: generating --broker none --layout clean-architecture with idempotency, dataprotection and locking builds clean where it failed before. The audittrail half cannot be proven the same way today — a generated app consumes the PUBLISHED Abstractions, so it needs the train. ## How both were missed, and the shape that would have caught them The nightly matrix had two clean shapes and neither could reach these. GmFourClean takes no features at all. GmOneClean keeps the default broker, which supplies Mediant.Behaviors to Application by accident through Goldpath.Messaging. GmCleanFeatures is the new shape: clean-architecture, deliberately broker-less, carrying the features whose code the layout MOVES. It ships WITHOUT audittrail, which is a decision rather than an oversight — that flag would keep the shape red until the train publishing the move, and a nightly shape known to be red teaches the team to ignore a red nightly. The release checklist's next-train adoptions owns adding it, with the reason, and the golden-manifests ledger carries the row. docs/upgrades/0.1.0-preview.9.md says what an adopter does: recompile. Five gates green. AuditTrail 9 tests, CLI 412 tests.
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.
Found by qorpe/coexist on 2026-09-09, generating that layout as the first adopter to want it. Two independent breaks, one shape of cause: the template puts feature-conditional code in
DomainandApplication, but only theApicsproj carried the feature-conditional package references.1 —
IAuditLoggedmoves toGoldpath.AbstractionsOrder.AuditTrail.cslands inDomainand needsIAuditLogged, which lived inGoldpath.AuditTrail— a package that pulls ASP.NET Core, EF Core andGoldpath.Data. Referencing that fromDomaininverts the dependency direction the layout exists to teach, so the reference is not the fix.Its five siblings are already where it should have been:
IAuditedEntity,ISoftDeletable,IMultiTenant,IIntegrationEvent,GoldpathPersonalDataGoldpath.AbstractionsIAuditLogged→Goldpath.AuditTrailGoldpath.AbstractionsBoth packages declare it in
namespace Goldpath, so the move is source-compatible — adopters recompile and change nothing.A
TypeForwardedTowas written first and withdrawn:PublicApiAnalyzerscannot reconcile a forwarded type, reporting RS0016 (not part of the declared public API) and RS0017 (declared but could not be found) for the same symbol in the same build. On a pre-1.0 preview train, a recompile is cheaper honesty than a suppression that outlives its reason.2 — the
Applicationproject gets the behaviours package it already usesCreateOrder.cscarries[Mediant.Behaviors.Attributes.Idempotent]underUseIdempotencyand lands inApplication— and no template csproj referencedMediant.Behaviorsat all. Invertical-slicethe file lands inApiand reaches it transitively throughGoldpath.Idempotency. Central package management makes the fix two lines: the conditional reference and itsPackageVersion.Proven today. Generating
--broker none --layout clean-architecture --features idempotency --features dataprotection --features lockingfrom the fixed template builds clean where it failed:The
audittrailhalf cannot be proven the same way today: a generated app consumes the publishedGoldpath.Abstractions, so it needs the train.How both were missed
The nightly matrix had two clean-architecture shapes and neither could reach these:
GmFourCleantakes no features at all.GmOneCleankeeps the default broker, which suppliesMediant.BehaviorstoApplicationby accident throughGoldpath.Messaging.GmCleanFeaturesis the new shape: clean-architecture, deliberately broker-less, carrying the features whose code the layout moves.It ships without
audittrail, and that is a decision rather than an oversight — that flag would keep the shape red until the train publishing the move, and a nightly shape known to be red teaches the team to ignore a red nightly. The release checklist's next-train adoptions owns adding it, with the reason written down;docs/strategy/golden-manifests-v1.mdcarries the row (the docs-freshness gate refused the shape until it did).Adopters
docs/upgrades/0.1.0-preview.9.md: recompile, nothing else. Adopters onvertical-slicedo nothing at all. Anyone who hand-addedMediant.Behaviorsto a clean-architectureApplicationproject can delete it — a duplicate is harmless either way.Verification