chore(sf): differentiate auto-accepted vs user-resolved escalations in audit
resolveEscalation gains an optional `source: "user" | "auto-mode"` parameter (default "user"). Auto-dispatch passes "auto-mode" when it auto-accepts. The UOK audit event type now flips between "escalation-user-responded" and "escalation-auto-accepted", and the payload includes a typed `resolvedBy` field. Why: a journal grep for user actions shouldn't return auto-mode events. Audit/observability tools can now filter cleanly without string-matching the rationale prefix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
00c13bc5a1
commit
c308a492d7
2 changed files with 7 additions and 1 deletions
|
|
@ -548,6 +548,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|||
state.activeTask.id,
|
||||
"accept",
|
||||
"auto-mode: accepted agent recommendation; user can override via /sf escalate",
|
||||
"auto-mode",
|
||||
);
|
||||
if (result.status === "resolved") {
|
||||
// Flags cleared; let the next dispatch cycle re-read state and
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ export function resolveEscalation(
|
|||
taskId: string,
|
||||
choice: string,
|
||||
rationale: string,
|
||||
source: "user" | "auto-mode" = "user",
|
||||
): ResolveEscalationResult {
|
||||
const task = getTask(milestoneId, sliceId, taskId);
|
||||
if (!task || !task.escalation_artifact_path) {
|
||||
|
|
@ -365,13 +366,17 @@ export function resolveEscalation(
|
|||
buildAuditEnvelope({
|
||||
traceId: `escalation:${milestoneId}:${sliceId}:${taskId}`,
|
||||
category: "gate",
|
||||
type: "escalation-user-responded",
|
||||
type:
|
||||
source === "auto-mode"
|
||||
? "escalation-auto-accepted"
|
||||
: "escalation-user-responded",
|
||||
payload: {
|
||||
milestoneId,
|
||||
sliceId,
|
||||
taskId,
|
||||
chosenOptionId: chosenOption?.id,
|
||||
rationale,
|
||||
resolvedBy: source,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue