Nuanced Policy Gates
Judgment-heavy policies evaluated inside check_write before any write. Prefer Pause over silent Allow when confidence is low. Full evidence on every decision.
Where it runs
Inside the existing Check Write step (called gate), after hard deterministic rules (idempotency, unknown key, requireApproval, stale authority), before mismatch / final Allow. Block and Pause never write. SDK guardedWrite unchanged.
Policy types (v1) + example thresholds
| Type | Default Pause when |
|---|---|
bias_fairness | Proxy contribution > 15% or proxy rank in top 3; protected attribute / unapproved alt data |
intent_semantic_drift | Goal embedding drift > 0.28 from playbook goal |
contextual_appropriateness | Open Sev-1, active renegotiation, or owner changed in last 7 days |
explanation_quality | Explanation completeness < 0.65 or key context fields missing |
second_order_effects | ≥ 3 downstream automations, or forecast / commission impact |
value_alignment | Optimizes a metric while violating documented business intent |
novelty_ood | OOD / novelty score above threshold (default 0.4) |
reversibility_cost | Irreversible write or compensation cost above configured threshold |
Thresholds live in each policy config and can be changed via API without a code deploy. Both rule thresholds and model scores (recommended / confidence) are supported (signalMode: hybrid).
Decision merge
- Any policy recommends Block → Block
- Else any policy recommends Pause → Pause
- Else → Allow (deterministic Check Write continues)
Emit signals on Write Intent
Orchestrator (or an upstream scorer) attaches nuancedSignals. No signals → nuanced gates do not change the decision (hard rules still apply).
await protect.guardedWrite({
intent: {
system: "Salesforce",
objectType: "Opportunity",
objectRef: "006xx",
field: "StageName",
newValue: "Closed Won",
authorityValue: "Eligible",
authoritySource: "billing_sor",
nuancedSignals: {
context: { recentComplaint: true, confidence: 0.6 },
explanation: { qualityScore: 0.35, missingContext: ["tenure"] },
reversibility: { irreversible: false, cost: "medium", confidence: 0.7 }
}
},
write: () => sf.sobject("Opportunity").update({ Id, StageName: "Closed Won" }),
});
Evidence trail
Every Pause or Block returns policyEvidence (schema nuanced_policy.v1) with, per fired policy:
- Policy name and version (plus id / type)
- Key signals that fired
- Confidence / signal strength
- Human-readable reason
- Timestamp
- Agent identity (
agentIdentityor agent name/id)
Pause / Block also append a Trace event with policyEvidence in metadata (same auditId as Check Write).
Create, version, attach, disable (no code deploy)
Dashboard session actions on /agentops-api.php:
list_nuanced_policies— catalog + defaults, or agent policies (agentId)set_nuanced_policies—policies[]replace,policy{}upsert,resetToDefaults, ordisableAll
// Upsert one versioned policy attached to Opportunity updates
{ "action": "set_nuanced_policies", "agentId": "ag_…",
"policy": {
"type": "intent_semantic_drift",
"version": "2",
"enabled": true,
"attach": { "objectTypes": ["Opportunity"], "actionTypes": ["update"], "agentRoles": ["*"] },
"config": { "goalDriftThreshold": 0.28 }
}
}
// Roll back to platform defaults
{ "action": "set_nuanced_policies", "agentId": "ag_…", "resetToDefaults": true }
// Disable all nuanced gates (hard rules still run)
{ "action": "set_nuanced_policies", "agentId": "ag_…", "disableAll": true }
Default when unset: all eight types enabled for *. Hard deterministic gates are unchanged either way.
Out of scope (v1)
- Auto-remediation or automatic policy rewriting
- Full fairness metric suite or model retraining
- Dedicated real-time human review UI (use Pause + kill switch + Trace)