feat: surface risk rationale to operator in approval prompt
Carry the full RiskSummary (level, signals, rationale) inline on ApprovalRequestedEvent instead of discarding it after assessment. The two server-side DTO builders (live ApprovalCoordinator path and replay DomainEventMapper path) now render real risk level, recommended action, signal factors, and the [code] rationale lines into the approval WebSocket message, with a consistent enum-name fallback when no assessment ran (tool path). RiskSummary/RiskSignal made @Serializable for event embedding; shared RiskSummary.toDto() lives next to RiskSummaryDto.
This commit is contained in:
+5
@@ -894,6 +894,7 @@ abstract class SessionOrchestrator(
|
||||
tier = domainRequest.tier,
|
||||
validationReportId = domainRequest.validationReportId,
|
||||
riskSummaryId = domainRequest.riskSummaryId,
|
||||
riskSummary = domainRequest.riskSummary,
|
||||
sessionId = sessionId,
|
||||
stageId = stageId,
|
||||
projectId = null,
|
||||
@@ -938,6 +939,9 @@ abstract class SessionOrchestrator(
|
||||
),
|
||||
)
|
||||
val riskSummaryId = RiskSummaryId(UUID.randomUUID().toString())
|
||||
// RiskAssessedEvent records the indexed level+action summary; ApprovalRequestedEvent carries the full
|
||||
// authoritative RiskSummary (signals + rationale). Both derive from the same assessment value so
|
||||
// they cannot diverge.
|
||||
emit(
|
||||
sessionId,
|
||||
RiskAssessedEvent(sessionId, stageId, riskSummaryId, riskSummary.level, riskSummary.recommendedAction),
|
||||
@@ -947,6 +951,7 @@ abstract class SessionOrchestrator(
|
||||
tier = riskSummary.level.toApprovalTier(),
|
||||
validationReportId = ValidationReportId(UUID.randomUUID().toString()),
|
||||
riskSummaryId = riskSummaryId,
|
||||
riskSummary = riskSummary,
|
||||
timestamp = Clock.System.now(),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user