Check Write extension · v1

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

TypeDefault Pause when
bias_fairnessProxy contribution > 15% or proxy rank in top 3; protected attribute / unapproved alt data
intent_semantic_driftGoal embedding drift > 0.28 from playbook goal
contextual_appropriatenessOpen Sev-1, active renegotiation, or owner changed in last 7 days
explanation_qualityExplanation completeness < 0.65 or key context fields missing
second_order_effects≥ 3 downstream automations, or forecast / commission impact
value_alignmentOptimizes a metric while violating documented business intent
novelty_oodOOD / novelty score above threshold (default 0.4)
reversibility_costIrreversible 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

  1. Any policy recommends Block → Block
  2. Else any policy recommends Pause → Pause
  3. Else → Allow (deterministic Check Write continues)
Risky but unclear cases should Pause. Do not silent-Allow when confidence is low.

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 (agentIdentity or 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_policiespolicies[] replace, policy{} upsert, resetToDefaults, or disableAll
// 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)