The four operator actions
When an operator opens a request-detail drawer and concludes the verdict was wrong, the workflow is one of four actions:
Each action is captured with the actor, the captured display label, the
IP, the user-agent, and a metadata snapshot. The audit trail is enough
for a SOC 2 reviewer to confirm the chain of custody after the fact.
The per-request review state
The dashboard request-detail drawer carries a Mark for review control. Marking a request flips itsreview_state to a defined value
and writes an operator-action audit row. The supported states are:
Transitions between states are themselves audit-logged
(
request.review_state_changed) with the actor, the prior state, and the
new state, so the chain “who decided this verdict was wrong, when?” is
queryable from the operator-action audit log.
The review state is a per-request operator annotation. It is not a
re-evaluation: the original verdict, matched policies, and audit
preview do not change. The platform never re-writes history; it adds
an annotation row.
request_logs.csv so a
fairness or audit review can filter on “blocks that were reviewed and
confirmed incorrect.”
A worked example
A customer-service agent is blocked from telling a customer their order status because a deny regex matched on the order id format. The operator’s path:- Open the request in the dashboard. The decision drawer shows the
matched policy was
pii-orderid-blocked,enforcement_statusisenforced, and the post-redaction preview reveals the block was triggered by an order-id pattern that overlaps a credit-card mask. - Mark for review with state
reviewed_incorrect. The operator adds a one-line note: “Order-id regex over-broad; collides with the CC mask.” - Edit the policy. They open the
pii-orderid-blockedpolicy, narrow the regex, and save. Apolicy.updaterow lands in the audit log with the captured metadata (priority, phase, target agents). - The SDK picks up the new policy on its next refresh. Subsequent calls with the same order-id pattern allow correctly.
- the review-state transition (operator, time, prior + new state, note),
- the
policy.updaterow (operator, time, policy id, metadata diff), - the
request_logsrows for that policy across the window, withverdictdistribution before and after the policy edit.
When to escalate, not edit
Some blocks are correct but uncomfortable. Asemantic_guard block on a
borderline harassment intent, an output regex block on an unusual
financial format, a pii_scan block on a customer-provided identifier
that turned out to be intentional — these are cases where the right
action is to escalate to a reviewer or to the compliance team, not
edit the policy.
The supported pattern is:
- Mark the request for review with state
escalated. - Send the request id (and optionally the post-redaction preview) to the human reviewer through your team’s normal channel — Slack, email, ticketing.
- Have the reviewer mark the request
reviewed_correctorreviewed_incorrectwhen they conclude.
request_logs.csv.
What we deliberately don’t ship
To be explicit about scope:- No end-user-facing appeal portal. EgisAI never sees the end user directly; the customer’s application does. Surfacing a “contest this decision” link to the end user is a customer-side feature — the SDK block path returns enough information (the matched policy id, the reason code, the post-redaction preview) for the customer’s application to render a help page or a support form.
- No automatic un-blocking. Marking a request
reviewed_incorrectrecords the operator’s judgement; it does not retroactively change the verdict. The historical row stays as the model saw it. - No “trust me” overrides. There is no mechanism for an operator to re-run a blocked call with the block disabled “just for this request”. If a class of calls is being incorrectly blocked, the path forward is to edit the policy and let the new ruleset apply going forward.
Choosing between raise and stub
Your code can see a block in two ways, picked by the on_block
configuration:
raise(default) raisesPermissionErrorwith the reason embedded. Your existing exception handlers can catch it and route to your application’s error path.stubreturns a framework-shaped refusal object — same shape as the provider would have produced, with content describing that the call was refused by policy.
stub; user-facing call paths usually use raise. See
Blocking behavior for full examples.
Roadmap
The capabilities below are designed and on the near-term roadmap, in this order:- First-class review-state column. A
request_logs.review_statecolumn plus a dashboard control to set it. The audit-evidence export surfaces the state as a column for fairness joins. - Reviewer-only role. A workspace role that can transition review state but cannot author policies. Useful for compliance teams that should review without touching the runtime rules.
- SLA timers on escalated reviews. Optional per-org timer that surfaces overdue escalations as a dashboard counter.
What’s next
Blocking behavior
Choosing between
raise and stub for end-user-facing call paths.Decision explainability
The four surfaces that explain why a call hit a verdict.
Policy change control
Who can edit policies, how every change is audited, and how the SDK picks up the new version.
Audit-evidence export
Export the review-state column for offline fairness or audit work.