Repository navigation
refactor(access): centralize live reads and isolate lifecycle (#857 E1) - #1055
Conversation
Opus security review: #1055 at
|
| Mutant | Result |
|---|---|
M1: zero rows → restricted (drop Count == 0) |
Red. AccessLookupTests failed 2 and AccessAuthorizationContractTests.AssignmentReadObservesIndependentCommitInTheSameScope failed |
M2: middleware always Resolve(true, []) |
FlockScopeMiddlewareTests stayed green (13/13). FlockScopeTests went red with 6 failures, including ScopedWorker_FlocksList_SeesOnlyAssignedFlock and ScopedWorker_UnassignedFlockDetail_Returns404 |
M3: UserManager + ICredentialEpochVerifier + IStepUpGrantService in the lifecycle |
Red. 3 failures, all on the poisonRedis: True rows |
M4: UserManager alone in the lifecycle |
Green (S2) |
For M2, FlockScopeTests is the class that guards the changed middleware line, not FlockScopeMiddlewareTests. It is listed in the PR's affected-classes.txt.
Head runs (each class alone; integration under sg docker)
AccessLookupTests 6/6, AccessAuthorizationContractTests 6/6, AccessLifecycleDependencyTests 7/7, ConfirmSaleOrderBoundaryTests 2/2, FlockScopeMiddlewareTests 13/13, ConfirmSaleAssignmentReadTests 1/1. The Application guards passed 14/14: FlockScopeGuardTests, ModuleLedgerRealTreeTests, CouplingMatrixRealTreeTests, TenantBypassRealTreeTests, AdapterReachRealTreeTests, SeamSurfaceRealAssemblyTests and PeerContractRealTreeTests. Logs are in /home/mforce/.cluckwork-slices/reviews/1055-opus-evidence/.
Code quality (P3, slice-scoped)
Thermo-nuclear review. The slice deletes more than it adds, and the main restructuring is already done: three local interpretations collapse into one answer owned by the lookup. No file crosses 1k lines (IdentityProvider.cs shrinks), and no new conditionals are added to shared paths.
- Q1: the
IReadOnlySet<Guid>?boundary usesnullfor the most permissive state. The middleware then has to check it twice:scope.Resolve(assigned is null, assigned is null ? [] : assigned)atFlockScopeResolutionMiddleware.cs:58. A named result (S1) would remove both checks. - Q2 (accepted):
AccessAccountLifecycleonly forwards to two services. It is accepted as the Application port that E2 declares, and it mirrorsAccessOperations.
Ponytail review.
- Q3,
MustChangePasswordGateTests.cs:L276andStepUpAuthTests.cs:L712:delete:blank line left before the closing brace after the forwarders were removed. - Q3,
AccountProvisioner.cs:L2:shrink:using Cluckwork.Application.Features.Users;sits above...Features.Accounts. Sort it.
Net: -2 lines possible. The rest is lean.
PR #1055 independent Astra reviewApprove E1 at FindingP3, optional, E1 only: remove the now single-caller effective-role helper. Both Product checks
Independent verification172 passed, 0 failed, 0 skipped: 155 integration cases across 14 classes and 17 Application cases across 9 classes. Every invocation selected one class. Integration ran through
I also inspected the author's evidence. All 27 mutant records contain executed assertion failures. All 42 stored SQL/HTTP files match base/head exactly. The purge trace matches exactly; the verb trace matches after normalizing only E2's contract declaration, seeder conversions and deferred Common identity-port ownership claims remain outside this approval. Source unchanged; no commit or push. Local report: |
Before Access's contract is declared, assignment semantics are duplicated across three callers and lifecycle verbs construct the credential/Redis graph. This moves assignment interpretation into
IAccessLookup, routes live assignment admission through it, splits the lifecycle graph, and moves the original provisioning outcome instead of copying it.E1 of the approved E1/E2 split. E2 declares the 28-entry contract, converts the seeders and folds in #1023's two Access ownership claims. Refs #857.
Change map
The outcome move removes the three stale outcome symbols from Access→Commerce, Access→EggOperations and Access→Farm. The matrix is regenerated. Two tenant-bypass role-query rows are rekeyed to the private instance method with their query token hashes retained. #1037 T1–T4 and R3-1/R3-2, and #1047 F1/F2 land here. The approved #1041 session reshape deferral lands in E2's decision record.
Review in this order
IAccessLookupandAccessLookup: null means zero rows or any null-flock row; database and cancellation failures propagate. The read keeps its tenant filter, user predicate,AsNoTracking, full materialization and scoped context.AssignFlockHandler: resolved-actor/role gates, proof-first admission and account→order→live-role→assignments→stock sequencing.IAccessAccountLifecycle,AccessAccountLifecycle, CLI wiring and the original outcome move. The new dependency graph is exercised through the real registrations and commands.Properties to try to refute
ICurrentUseraliases the scopedCurrentUserContext; another scope has a different actor and lookup. Their tenant state remains aligned with the context filter.Mutation proof
All 27 mutants fail an executed named assertion. No compilation, inotify, Docker or other environment error is counted as red. Each mutation is restored before the next run.
assignment-before-account-lockConfirmSaleAssignmentReadTests.ConfirmSale_ParkedOnTheAccountLock_ReadsAnAssignmentRemovalThatCommittedWhileItWaitedassignment-before-order-lockConfirmSaleOrderBoundaryTests.ConfirmReadsRoleAndAssignmentsAfterTheOrderLock(disableWorker: True)cache-assignmentsAccessAuthorizationContractTests.AssignmentReadObservesIndependentCommitInTheSameScopedisplay-role-instead-of-live-roleAccessAuthorizationContractTests.AssignmentAdmissionRefusesDisabledAndMultipleRoleTargets(disabled: True)drop-active-member-predicateConfirmSaleOrderBoundaryTests.ConfirmReadsRoleAndAssignmentsAfterTheOrderLock(disableWorker: True)drop-assignment-cancellationAccessLookupTests.GetAssignedFlocks_UsesTheScopedContextsTenantAndForwardsCancellationdrop-one-assigned-flockAccessLookupTests.GetAssignedFlocks_ReturnsNullForMixedFarmWideRowsAndOnlyThatUsersAssignedSetdrop-role-account-predicateAccessLookupTests.GetEffectiveRole_AnswersOnlyForTheAccountItIsAskedAboutdrop-tenant-filterAccessLookupTests.GetAssignedFlocks_UsesTheScopedContextsTenantAndForwardsCancellationdrop-unresolved-tenant-refusalAccessLookupTests.GetAssignedFlocks_RefusesAnUnresolvedTenantdrop-user-predicateAccessLookupTests.GetAssignedFlocks_ReturnsNullForMixedFarmWideRowsAndOnlyThatUsersAssignedSeteffective-role-before-proofAccessAuthorizationContractTests.MissingAssignmentProofReadsNoTargetsForKnownOrUnknownUsersidentity-in-lifecycleAccessLifecycleDependencyTests.RealLifecycleVerbNeverConstructsIdentityOrRedis(verb: "rename-account", poisonRedis: True)mixed-farm-wide-is-restrictedAccessLookupTests.AWorkerWithAFlockRowAndAFarmWideRow_IsUnrestrictedprinted-provision-password-corruptProvisionAccountCommandTests.ProvisionAccount_UnderDmlOnlyRole_PrintsOneWorkingPasswordAfterCommitprovision-account-id-corruptAccessLifecycleDependencyTests.ProvisioningOutcomeNamesTheCommittedFarmAndOwnerAndCarriesTheirWorkingPasswordprovision-owner-email-corruptAccessLifecycleDependencyTests.ProvisioningOutcomeNamesTheCommittedFarmAndOwnerAndCarriesTheirWorkingPasswordprovision-slug-corruptAccessLifecycleDependencyTests.ProvisioningOutcomeNamesTheCommittedFarmAndOwnerAndCarriesTheirWorkingPasswordredis-in-lifecycleAccessLifecycleDependencyTests.RealLifecycleVerbNeverConstructsIdentityOrRedis(verb: "suspend-account", poisonRedis: True)role-before-account-lockSaleAllocationPolicyTests.ConfirmSale_ParkedOnTheAccountLock_IsForbidden_WhenTheActorIsDisabledWhileItWaitsrole-before-order-lockConfirmSaleOrderBoundaryTests.ConfirmReadsRoleAndAssignmentsAfterTheOrderLock(disableWorker: False)second-actor-instanceAccessAuthorizationContractTests.ScopedActorAndLookupShareStateAndRemainIndependentsingleton-actorAccessAuthorizationContractTests.ScopedActorAndLookupShareStateAndRemainIndependentsingleton-lookupAccessAuthorizationContractTests.ScopedActorAndLookupShareStateAndRemainIndependentswallow-assignment-failureAccessAuthorizationContractTests.AssignmentReadFailurePropagatesInsteadOfGrantingUnrestrictedScopetarget-before-proofAccessAuthorizationContractTests.MissingAssignmentProofReadsNoTargetsForKnownOrUnknownUserszero-is-restrictedAccessLookupTests.GetAssignedFlocks_ReturnsNullForMixedFarmWideRowsAndOnlyThatUsersAssignedSetThe display-role mutation explicitly maps the list's
Workerlabel to the Worker enum. Feeding that label intoRoles.ResolveEffectivewould create a different mutation, because actual Workers have zero role rows. The corrected mutation admits the disabled target and fails the status assertion. The order-lock mutations fail the exact transaction statement sequence, in addition to the parked-request behavior.Security-suite edits approved by the owner
The four mechanical edits are: delete the obsolete decorator forwarder in
MustChangePasswordGateTestsandStepUpAuthTests; add the Users import inAccountProvisioningTestsandTwoFarmIsolationMatrixTests. Their assertions remain intact. Separate tidy-ups fix the shared tenant fixture and two stale comments. New tests cover the additional security observations.Deslop and quality record
Ran deslop,
pstack:thermo-nuclear-code-quality-reviewandponytail-reviewmyself. Deleted duplicate assignment interpretation, the outcome copy/mapping and the dead role forwarding surface. ReusedTestHarness.SeedSalesOrderAsyncin the new lock-boundary fixture, deleting unrelated HTTP setup. No file crosses 1000 lines; the two existing giant files shrink. No remaining structural or over-engineering finding. Independent Astra and Opus security review remains the hold point for this PR.Validation
@tand quoted/numericelapsedonly.Local evidence:
/home/mforce/.cluckwork-slices/reviews/857-E1-evidence/; quality reports:/home/mforce/.cluckwork-slices/reviews/857-E1-quality/. Scratch harnesses and mutation tools stay outside the repository.