← All courses ← Course home

Lesson 04 of 05

Add a judge and escalate

When voters split, a judge session chooses approve, reject, or escalate. Escalate stops the app and shows a person.

Agent brief (llms.md)

A split vote is not a yes. When the tally is below the threshold, or when voters disagree on the action text, send the packet to a judge. The judge is another session, or the judge seat on a Dynamic Profile. It sees the votes, not a chance to invent a new action.

TallyPass or split
JudgeApprove, reject, escalate
PersonIf escalate
@Generable
struct Judgment {
    @Guide(description: "approve, reject, or escalate")
    var decision: String
    var reason: String
}

func judgeVotes(packet: String) async throws -> Judgment {
    let board = ReviewBoard()
    board.seat = .judge
    let session = LanguageModelSession(profile: ReviewProfile(board: board))
    let reply = try await session.respond(to: packet, generating: Judgment.self)
    return reply.content
}

enum Gate: String {
    case allow
    case block
    case escalate
}

func resolve(specialists: [Specialist], votes: [String: Vote], threshold: Double) async throws -> Gate {
    if approved(specialists: specialists, votes: votes, threshold: threshold) {
        return .allow
    }
    let packet = votes.map { "\($0.key): \($0.value.choice) \($0.value.reason)" }.joined(separator: "\n")
    let judgment = try await judgeVotes(packet: packet)
    switch judgment.decision.lowercased() {
    case "approve": return .allow
    case "escalate": return .escalate
    default: return .block
    }
}

Escalation is a UI state. Show the proposed action, the votes, and the judge reason. Wait for a person. Do not call the side-effect tool from the judge session. If you need a safer model for the judge, set .model(SystemLanguageModel.default) and keep the work on device. Use Private Cloud Compute only when you have already redacted the packet. That redaction is in Stop prompt attacks and leaks.

VotersWeighted tally
JudgeOnly on a split
PersonOn escalate

Read Pause and resume long AI jobs, Stop prompt attacks and leaks, and Talk to tools with MCP if the wait for a person must survive backgrounding.

Rule. Escalate means stop and show a person. It does not mean try the action anyway.

Next, bind the gate to the tool so the app cannot skip it.

Key concepts

  • A split vote goes to a judge session or a judge seat.
  • The judge returns approve, reject, or escalate.
  • Escalate means stop and show a person, not try the action anyway.
  • The judge sees votes, not permission to invent a new action.

Takeaways

  • Do not call a side-effect tool from the judge session.
  • Keep the judge on-device unless you redact first.
  • Escalation is a UI state that waits for a person.