Skip to main content
Intelligent Authorization handles governed requests Cedar returns as no_match. The Court — a panel of LLM judges — deliberates and returns a permit, forbid, or unavailable ruling with a full audit trail. Audit events, permissions, and the API surface use the canonical name Judges for this capability (e.g. judges.ruling.issued, judges.view, the Judges Connect service). The user-facing label is “Intelligent Authorization”. The implementation prefix is judges.*.
Renamed from Moot in the 2026-06 release. Audit event types (moot.*), permissions (moot.view/moot.manage), CLI (dome moot), MCP tools (dome_moot_*), the Moot Connect service, and the Decision.depth value "intelligent" are all renamed to judges. Audit rows written before the cutover keep their original event-type strings and remain readable. Everything else is a hard rename with no alias.

Tier model

Authorization evaluates in tiers. Tier 0 always runs. The Court runs only when Tier 0 cannot decide. A Tier 0 permit or forbid short-circuits. The Court never convenes. A Tier 0 no_match escalates straight to The Court. forbid always wins: a deterministic forbid cannot be overridden by The Court.
Intermediate tiers (single-judge cache, escalation gate) are not shipped. no_match goes directly to The Court.

Workspace mode

Each workspace runs The Court in one of three modes. The mode controls whether judge rulings affect the agent’s outcome. audit is the shipping path: enable it, watch rulings accumulate, tune the panel and constitution, then flip to live. New workspaces default to disabled. no_match is the default convening trigger, but when The Court convenes is configurable per workspace. A workspace can also escalate deterministic permits and forbids that opt in via a per-bundle court-scope marker (policy_escalation), or every governed decision (all). Refer to when the Court convenes for the full trigger and effect model.

Judges

A judge is an LLM persona that votes on a single case. Each judge ships with:
  • System prompt: base instructions prepended to every deliberation.
  • Personality axes: {key: level} selections against the platform catalog (e.g. strictness: very_high, evidence_weighting: skeptical). ListPersonalityAxes is platform reference data with no permission gate, so it has no *.denied audit variant.
  • Weight: high, medium, or low. Sets the judge’s influence on the tally.
Two kinds exist:
  • Preconfigured judges ship seeded per workspace: Compliance Judge, Security Skeptic, Meticulous Auditor. Their definitions are immutable. You can still enable, disable, and reweight them in the panel.
  • Custom judges are workspace-defined. Create, update, and delete them through the dashboard or API.
Attempts to edit or delete a preconfigured judge return permission_denied with reason: "preconfigured_immutable".

Panel and constitution

The panel is the per-workspace seating chart: which judges sit, whether they are enabled, and what weight each carries. The constitution is a workspace-wide list of clauses prepended verbatim to every judge’s prompt. Use it to encode policy that is too nuanced for Cedar, such as escalation criteria, customer-specific norms, or regulatory framing. Clauses are advisory: judges weigh them against the evidence and may override.
example constitution clause

Per-case deliberation context

Every judge prompt opens with a deliberation_context block built per case from the deterministic baseline. The block states why The Court convened, what Cedar decided, which policy fragment determined it, and how far the judge is authorized to move the outcome. The shared system prompt then points the judge at this block instead of asserting a fixed premise. This matters because The Court convenes on more than no_match. Under policy_escalation and all, Cedar already returned an explicit permit or forbid, and the judge is arbitrating an override, not filling a policy gap. The framing has to match the case. The block is assembled at deliberation time from the live baseline, so the framing corrects all workspaces immediately. No judge re-seed or constitution change is required. Stored seed prompts are not rewritten. The premise and authority lines are factual and symmetric. They tell the judge what the baseline is and what the clamp will enforce. They never tell the judge which way to lean. A reduce-clamped judge that votes permit is still recorded. The directional clamp applied at the Evaluate boundary is what keeps the baseline.
Attacker-influenced fields (convening_reason, determining_fragment) are sanitized at render time. Control characters and line breaks are stripped so a crafted policy id or convening reason can’t forge prompt structure. cedar_baseline is a closed enum and needs no sanitization.

Voting and tally

Each judge casts one of five votes. The deliberation engine maps votes to numeric values and weights to multipliers, then sums: aggregated_weighted_score = sum(weight × vote_value) across non-errored judges. The engine maps that score to permit or forbid using configured thresholds. A judge that errors or times out produces a vote of unspecified plus a non-empty error. The ruling proceeds with the remaining judges and is marked partial: true.

Fail-closed on Court failure

If fewer than two judges return a usable vote, The Court returns court_unavailable. This covers the all-judges-error case (model unavailable, timeout, malformed tool output) but also any case that falls below the two-vote quorum, such as one judge voting while the other two time out. The agent’s request is denied with depth: "judges" and reason: "court_unavailable". The ruling row is still persisted with final_outcome: "court_unavailable" so operators can debug. A distinct judges.court.unavailable.denied audit event fires on every Court failure. The event carries agent_id, action, resource, mode, partial, latency_ms, and ruling_id. Refer to Judges concept. There is one synthetic variant of the same event. If live mode produces a Court permit but the ruling row fails to persist, the service cannot flip the agent outcome without a forensic record. It fails closed to a deterministic deny and emits judges.court.unavailable.denied with reason: "persistence_failed" and would_have: "permit" in place of ruling_id. This is the only path where the event fires without a corresponding ruling row.

Decision shape

When The Court rules, the Decision response carries depth: "judges" and ruling_id, the persisted ruling’s id. Decision stays lean. Callers that need the full deliberation record fetch it via Judges.GetRuling.
decision-with-ruling.json
The full Ruling returned by Judges.GetRuling carries the per-judge vote tally, applied constitution clauses, tier breakdown, and replayability snapshots (the judge prompts, constitution bodies, weighting config, LLM target, effective-policy content hash, and personality-axes catalog version in effect at deliberation time):
ruling-from-Judges.GetRuling.json
In audit mode the response reports the deterministic outcome (allowed: false, depth: "deterministic") and stamps ruling_id on the Decision so the dashboard can render “would have permitted / forbidden”. The reason field is suffixed with (audit mode: court would have permitted) (or forbidden). The ruling is persisted and queryable but does not change the agent’s outcome.

Permissions

Workspace admin and operator receive both. security, developer, and viewer receive judges.view only. Refer to Permissions Model concept.

Next steps

With that Intelligent Authorization model in mind, continue with: