test(arch): the F105 architecture fitness suite — six laws, front-and-center (T211–T215) - #407
Merged
Conversation
…RIES 290–294) 24 pending specs across Story290–294; GenWave.Architecture.Tests sln-added; library adoption + exemption mechanism are T211's to build.
…es (T211, STORY-290) - ArchUnitNET 0.13.3 adopted for L2 (Postgres confinement) — method-body reach, not just declared references. Both ArchUnitNET and its runner-up (NetArchTest.eNhancedEdition) silently under-cover assemblies not explicitly loaded up front, so L1 and L4-references use different techniques instead (recorded in the csproj comment): L1 hand-rolls an AssemblyRef metadata scan (exhaustive over direct references); L4-references reads the project's own build-output deps.json libraries map (a name-prefix check has a proven bypass — a System.*-named third-party package ships straight into the dependency closure without ever failing a "System" prefix check). - Named+dated exemption baseline: 2 designed composition-root entries (NpgsqlDataSource wiring, not querying) + 5 pre-existing debt entries stamped gh-#406, all failing on any NEW violation not on the list. - Hermetic per-law probes (Fixtures/L2Probe, Fixtures/L4Probe, and a stable third-party assembly for L1) prove each detector discriminates without coupling the proof to production's live dependency graph.
…etadata scan (T212, STORY-291) - Hand-rolled System.Reflection.Metadata scanner (flat type-table walk, compiler-generated roll-up) closes the async-lambda hole ArchUnitNET can't see — a nested compiler-generated type inside another never surfaces in ArchUnitNET's graph. - Forbid widened to the 5-type handler/invoker family (HttpClient, HttpMessageInvoker, HttpMessageHandler, HttpClientHandler, SocketsHttpHandler) — a working outbound client built without ever naming HttpClient still trips the law. - Program.cs source-text pin: exactly 3 AddHttpClient registrations, AllowAutoRedirect=false, and no raw hand-rolled client. - Self-resolving seam and exemption lists — a deleted/typo'd entry now reds instead of silently matching nothing. - AllProductionAssemblies factory on ProductionAssemblies, shared by L2 and L3 (and future T213/T214 laws) instead of copy-pasted lists.
…able and Core-free (T213, STORY-291) - Reflection-based member-shape detector for L4-immutability: init-only detected via the IsExternalInit required custom modifier; interface setters, required members, statics, and nested types all covered. - L6 via the AssemblyRef scan scoped to GenWave.Core — independently valuable, not just sharper wording over L4-references: a raw file-Reference bypasses deps.json's library map entirely, mutation-proven at review. - Zero violations found in either law; no baseline entries needed.
… (T214, STORY-292)
- Reflection-based detector: no metadata-table workaround needed, unlike L3 — nested/compiler-
generated types are visible by Assembly.GetTypes()'s own documented contract; still rolled up to
the outermost declaring type for legible attribution.
- One growth-tolerant reservation list ({ReservedNamespace, RulingReference, Reason}), seeded
GenWave.Host.Context -> gh-#378 and GenWave.Host.Ads -> gh-#380, both citing F105.4.
- Boundary matching reuses the one shared AssemblyReferenceScan.HasFamilyPrefix instead of a
hand-rolled duplicate; a same-prefix-lookalike fixture guards the boundary at the L5 layer too.
- ProductionAssemblies.HasType taught member- and assembly-level granularities (T213 review
carry-forward), with BindingFlags.DeclaredOnly closing the inherited-object-member blind spot.
…suite↔doc parity (T215, STORY-293) - Seven-id table mirroring LawId 1:1 (drop a row → exactly that id red, both directions) - F105.2's never-baseline-your-own-change sentence ships - Seam criterion verbatim with the demonstrated-need clause - Honest L2 wording (designed exemption vs gh-#406 baselines) - LawId.IdPattern single-sources the id shape (parser + All guard consume it) - SolutionLocator.Root() extracted - knownLawIds carry-forward closed via LawId.All
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
🏛️ What
PR 1 of the F105 adoption slice (SPEC F105.1–F105.5, gh-#398/#399/#400): the architecture laws become executable fitness tests running inside the normal
dotnet testgate, and the contract goes front-and-center in CONTRIBUTING.md.tests/GenWave.Architecture.Testssln-addeddeps.jsonlibraries map after review proved aSystem.*-prefix bypassProgram.cssource-text pin (3 registrations,AllowAutoRedirect = false, no raw clients)required, statics, nested types all covered) + L6 (independently valuable: a raw file<Reference>bypassesdeps.json— mutation-proven)Context→#378,Ads→#380; one shared dot-boundary helper guarded at two layersLawId— drop a row and exactly that id reds, both directions) + seam criterion with the demonstrated-need clause + F105.2's "never baseline your own change" sentence✅ Gates
System.*L4 bypass, the async-lambda L3 blindness, six shipped-doc wording defects including one false claim. All fixes mutation-proven.🚦 Next
PR 2 (
feat/f105-seams, T216–T217): the generated SEAMS.md + CI byte-diff rider — building now, targets main after this merges.