IDE Navigation Chain
From any layer, "Find All References" on UserRolesFeature shows the entire traceability chain:
UserRolesFeature <-- Layer 1: requirement definition
|-- IUserRolesSpec <-- Layer 2: [ForRequirement(typeof(UserRolesFeature))]
| |-- .AssignRole <-- Layer 2: [ForRequirement(..., nameof(...AdminCanAssignRoles))]
| |-- .EnforceReadOnlyAccess <-- Layer 2: [ForRequirement(..., nameof(...ViewerHasReadOnlyAccess))]
| '-- .VerifyImmediateRoleEffect <-- Layer 2: [ForRequirement(..., nameof(...RoleChangeTakesEffectImmediately))]
|-- AuthorizationService <-- Layer 3: [ForRequirement(typeof(UserRolesFeature))]
| |-- .AssignRole <-- Layer 3: [ForRequirement(..., nameof(...AdminCanAssignRoles))]
| '-- ...
'-- UserRolesTests <-- Layer 4: [TestsFor(typeof(UserRolesFeature))]
|-- .Admin_can_assign_role <-- Layer 4: [Verifies(..., nameof(...AdminCanAssignRoles))]
|-- .Non_admin_cannot_assign_roles <-- Layer 4: [Verifies(..., nameof(...AdminCanAssignRoles))]
'-- ...UserRolesFeature <-- Layer 1: requirement definition
|-- IUserRolesSpec <-- Layer 2: [ForRequirement(typeof(UserRolesFeature))]
| |-- .AssignRole <-- Layer 2: [ForRequirement(..., nameof(...AdminCanAssignRoles))]
| |-- .EnforceReadOnlyAccess <-- Layer 2: [ForRequirement(..., nameof(...ViewerHasReadOnlyAccess))]
| '-- .VerifyImmediateRoleEffect <-- Layer 2: [ForRequirement(..., nameof(...RoleChangeTakesEffectImmediately))]
|-- AuthorizationService <-- Layer 3: [ForRequirement(typeof(UserRolesFeature))]
| |-- .AssignRole <-- Layer 3: [ForRequirement(..., nameof(...AdminCanAssignRoles))]
| '-- ...
'-- UserRolesTests <-- Layer 4: [TestsFor(typeof(UserRolesFeature))]
|-- .Admin_can_assign_role <-- Layer 4: [Verifies(..., nameof(...AdminCanAssignRoles))]
|-- .Non_admin_cannot_assign_roles <-- Layer 4: [Verifies(..., nameof(...AdminCanAssignRoles))]
'-- ...Every link is a typeof() or nameof() -- Ctrl+Click navigable, refactor-safe, compiler-checked.
Source-Generated Traceability
The Roslyn source generator, referenced by all projects as an analyzer, cross-references [ForRequirement], [TestsFor], and [Verifies] attributes to produce:
Traceability Matrix
// Generated: TraceabilityMatrix.g.cs
public static class TraceabilityMatrix
{
public static IReadOnlyDictionary<Type, TraceabilityEntry> Entries { get; } =
new Dictionary<Type, TraceabilityEntry>
{
[typeof(UserRolesFeature)] = new TraceabilityEntry(
RequirementType: typeof(UserRolesFeature),
Implementations: new[]
{
new ImplementationRef(typeof(AuthorizationService), typeof(IUserRolesSpec))
},
Tests: new[]
{
new TestRef(typeof(UserRolesTests), "Admin_can_assign_role_to_another_user",
nameof(UserRolesFeature.AdminCanAssignRoles)),
new TestRef(typeof(UserRolesTests), "Non_admin_cannot_assign_roles",
nameof(UserRolesFeature.AdminCanAssignRoles)),
new TestRef(typeof(UserRolesTests), "Viewer_cannot_write",
nameof(UserRolesFeature.ViewerHasReadOnlyAccess)),
new TestRef(typeof(UserRolesTests), "Viewer_can_read",
nameof(UserRolesFeature.ViewerHasReadOnlyAccess)),
new TestRef(typeof(UserRolesTests), "Role_change_invalidates_cache_immediately",
nameof(UserRolesFeature.RoleChangeTakesEffectImmediately)),
},
AcceptanceCriteriaCoverage: new Dictionary<string, int>
{
[nameof(UserRolesFeature.AdminCanAssignRoles)] = 2,
[nameof(UserRolesFeature.ViewerHasReadOnlyAccess)] = 2,
[nameof(UserRolesFeature.RoleChangeTakesEffectImmediately)] = 1
}),
};
}// Generated: TraceabilityMatrix.g.cs
public static class TraceabilityMatrix
{
public static IReadOnlyDictionary<Type, TraceabilityEntry> Entries { get; } =
new Dictionary<Type, TraceabilityEntry>
{
[typeof(UserRolesFeature)] = new TraceabilityEntry(
RequirementType: typeof(UserRolesFeature),
Implementations: new[]
{
new ImplementationRef(typeof(AuthorizationService), typeof(IUserRolesSpec))
},
Tests: new[]
{
new TestRef(typeof(UserRolesTests), "Admin_can_assign_role_to_another_user",
nameof(UserRolesFeature.AdminCanAssignRoles)),
new TestRef(typeof(UserRolesTests), "Non_admin_cannot_assign_roles",
nameof(UserRolesFeature.AdminCanAssignRoles)),
new TestRef(typeof(UserRolesTests), "Viewer_cannot_write",
nameof(UserRolesFeature.ViewerHasReadOnlyAccess)),
new TestRef(typeof(UserRolesTests), "Viewer_can_read",
nameof(UserRolesFeature.ViewerHasReadOnlyAccess)),
new TestRef(typeof(UserRolesTests), "Role_change_invalidates_cache_immediately",
nameof(UserRolesFeature.RoleChangeTakesEffectImmediately)),
},
AcceptanceCriteriaCoverage: new Dictionary<string, int>
{
[nameof(UserRolesFeature.AdminCanAssignRoles)] = 2,
[nameof(UserRolesFeature.ViewerHasReadOnlyAccess)] = 2,
[nameof(UserRolesFeature.RoleChangeTakesEffectImmediately)] = 1
}),
};
}Compiler Diagnostics
The generator emits Roslyn diagnostics -- not runtime checks, but IDE warnings and CI build output:
warning REQ001: UserRolesFeature -- all 3 acceptance criteria have tests (100% coverage)
warning REQ002: JwtRefreshStory -- 0/2 acceptance criteria have tests (0% coverage)
-> Missing: TokensExpireAfterOneHour, RefreshExtendsBySevenDays
warning REQ003: No class found implementing IJwtRefreshSpec
-> JwtRefreshStory has a specification but no domain implementationwarning REQ001: UserRolesFeature -- all 3 acceptance criteria have tests (100% coverage)
warning REQ002: JwtRefreshStory -- 0/2 acceptance criteria have tests (0% coverage)
-> Missing: TokensExpireAfterOneHour, RefreshExtendsBySevenDays
warning REQ003: No class found implementing IJwtRefreshSpec
-> JwtRefreshStory has a specification but no domain implementationThese appear in the IDE Error List and in CI build output. No runtime overhead. No reflection.