docs+code: close Theme 1 — 24 design-doc / XML-doc drift findings

Doc/XML-comment drift + small adherence fixes across 17 modules. Highlights:
- Host-017: site CoordinatedShutdown ordering — SiteStreamGrpcServer gains
  CancelAllStreams() (refuse new streams, cancel active), wired into
  Program.cs site branch via ApplicationStopping.
- InboundAPI-021: ParentExecutionId now travels on RouteToGet/SetAttributes
  symmetric with RouteToCallRequest; RouteHelper stamps from _parentExecutionId.
- ClusterInfra-012: ClusterOptionsValidator now requires both seed nodes.
- Comm-018: SiteCommunicationActor.HeartbeatMessage.IsActive derived from
  cluster leader check (was hardcoded true).
- DM-020: reconciliation audit row attributes the current user, not prior deployer.
- SEL-019: EventLogPurgeService early-exits on standby via active-node check.
- Plus comment/XML-doc accuracy fixes across AuditLog, ConfigurationDatabase,
  NotificationOutbox, SiteRuntime, SiteCallAudit; doc refreshes for Component-
  Commons / -ManagementService / -CLI / -ExternalSystemGateway / -HealthMonitoring
  / -Transport / -ConfigurationDatabase; CD-023 index-name doc alignment.

11 new regression tests (RouteHelper x4, SiteStreamGrpcServer x2,
ClusterOptionsValidator x1, SiteCommunicationActor x1, DeploymentService x1,
EventLogPurgeService x3). Build clean (0 warnings); InboundAPI/Communication/
Host suites all green. README regenerated: 112 open (was 136).
This commit is contained in:
Joseph Doherty
2026-05-28 06:28:31 -04:00
parent e3ca9af1be
commit 487859bff0
51 changed files with 940 additions and 188 deletions
@@ -909,6 +909,50 @@ public class DeploymentServiceTests : TestKit
Assert.Equal("sha256:target", prior.RevisionHash);
}
// ── DeploymentManager-020: reconciliation audit attributes to the CURRENT user, not the prior deployer ──
[Fact]
public async Task DeployInstanceAsync_Reconciled_AuditAttributesCurrentUserNotPriorDeployer()
{
// DeploymentManager-020: a redeploy that reconciles a timed-out prior
// record must be audited as the action of the user driving THIS
// redeploy — not the user who originally issued the now-reconciled
// deployment. The prior deployer is preserved in the detail object so
// forensics still see who started the rescued run.
var instance = new Instance("ReconcileAuditUser")
{
Id = 73, SiteId = 1, State = InstanceState.NotDeployed
};
_repo.GetInstanceByIdAsync(73, Arg.Any<CancellationToken>()).Returns(instance);
SetupValidPipeline(73, "ReconcileAuditUser", "sha256:target");
var prior = new DeploymentRecord("dep-prior-73", "originalUser")
{
InstanceId = 73,
Status = DeploymentStatus.InProgress,
RevisionHash = "sha256:target"
};
_repo.GetCurrentDeploymentStatusAsync(73, Arg.Any<CancellationToken>()).Returns(prior);
_repo.GetDeployedSnapshotByInstanceIdAsync(73, Arg.Any<CancellationToken>())
.Returns((DeployedConfigSnapshot?)null);
var commActor = Sys.ActorOf(Props.Create(() =>
new ReconcileProbeActor(siteHash: "sha256:target", failQuery: false)));
var service = CreateServiceWithCommActor(commActor);
var result = await service.DeployInstanceAsync(73, "currentUser");
Assert.True(result.IsSuccess);
// DeploymentManager-020: audit row's actor is the current user.
await _audit.Received().LogAsync(
"currentUser", "DeployReconciled", "Instance", "73", "ReconcileAuditUser",
Arg.Any<object>(), Arg.Any<CancellationToken>());
// And the prior deployer was NOT used as the actor.
await _audit.DidNotReceive().LogAsync(
"originalUser", "DeployReconciled", "Instance", "73", "ReconcileAuditUser",
Arg.Any<object>(), Arg.Any<CancellationToken>());
}
// ── DeploymentManager-012: LifecycleCommandTimeout must actually bound lifecycle commands ──
[Fact]