Arcezia provides runtime verification for autonomous AI agents. Before executing consequential actions, your agent queries Arcezia and receives a signed certificate — ALLOW, REVIEW, or BLOCK — evaluated strictly against grounded evidence. The verification engine is cloud-hosted; the client SDK performs zero inference.
No local models or heavy infrastructure required. All verification evaluates securely via api.arcezia.com.
Sign up self-serve at arcezia.com, or mint a developer key via cURL:
curl -X POST https://api.arcezia.com/v1/signup \ -A "arcezia-client/1.0" \ -H "Content-Type: application/json" \ -d '{"email": "developer@company.com"}' # Returns 202 for every address. No key is returned here: sign in at app.arcezia.com and issue your key once, on the Keys page.
Store your key immediately: It is issued in the dashboard and shown only once. The returned key holds the owner role, which is required for setup operations (registering probes, upload custom domains). Live keys begin with ar_live_...; development keys begin with ar_test_....
WAF & Direct REST Calling Gotchas: Always pass a valid User-Agent header (e.g. -A "arcezia-client/1.0"). Default scripting client signatures trigger Cloudflare/WAF block 1010. When making REST calls directly, authenticate via Authorization: Bearer ar_live_... (X-API-Key is rejected with 422).
pip install "arcezia[langchain]" # or [openai], [anthropic], [llamaindex], [all] export ARCEZIA_API_KEY="ar_live_..."
import arcezia # The task defines scope. The envelope says what this agent may do at most — # without it, "is this action part of the assigned job" has no answer and # nothing reaches ALLOW. az = arcezia.Arcezia(task="report on last year's events") az.start_session(capability_envelope={ "allowed_domains": ["database_ops"], "allowed_action_types": ["execute_sql"], }) # Request safety verification before running a tool cert = az.verify( action_type="execute_sql", action_description="SELECT COUNT(*) FROM events", domain="database_ops" ) print(cert.verdict) # REVIEW on a fresh account — see the next step print(cert.missing) # ['action_direction_is_outbound', 'action_crosses_trust_boundary', # 'action_involves_sensitive_data', ...] — these three first; the rest are # approval and authority facts a read no longer needs once these are declared
REVIEW, not ALLOW, on a fresh account. Scope is established by the
envelope, but three facts about this read cannot be seen from the statement itself —
whether it sends data out, crosses your organisation's boundary, or touches sensitive
data. The engine does not read "nothing visible" as "safe"; it holds the action and
names the three facts in cert.missing, with
absence_channel reading undeclared.
You, not the agent, decide per action type which of those absences may be read as
"not present" (Declarations, admin role). Declare only the
action types your agent uses and only the facts you can vouch for; never "*".
Two more facts describe the tool itself rather than the call — whether it makes a lasting
change (action_creates_persistent_mutation) and whether what it does can
be undone (action_is_structurally_irreversible). Declare those for a
specific tool only (a read-only lookup, say): "*" is refused for them, and
a write the engine detects in the call always wins over the declaration.
curl -X POST https://api.arcezia.com/v1/declarations \ -H "Authorization: Bearer ar_live_..." \ -H "Content-Type: application/json" \ -d '{ "declared_absent": { "action_direction_is_outbound": ["execute_sql"], "action_crosses_trust_boundary": ["execute_sql"], "action_involves_sensitive_data": ["execute_sql"] } }'
cert = az.verify(
action_type="execute_sql",
action_description="SELECT COUNT(*) FROM events",
domain="database_ops"
)
if not cert.allow:
raise RuntimeError(f"Action held by Arcezia: {cert.summary}")
# Reached: scope declared, the three absences declared — the read returns ALLOW
print(f"Cleared for execution! Single-use credential: {cert.credential}")
A declaration never silences a fact the engine does detect; that detection stands and the action is held regardless of what was declared. Everything the engine does not detect, however, is read as "not present" for that action type. Declare a fact absent only if it is true of every statement that action type can carry. A declaration applies only to the action types it names.
A read clears once scope and the three absences are declared. A write does not, and this is the point at which most first integrations stop and wonder what went wrong.
cert = az.verify(
action_type="execute_sql",
action_description="UPDATE customers SET tier='pro' WHERE id = 42",
domain="database_ops"
)
print(cert.verdict) # REVIEW
print(cert.missing) # ['action_scope_is_mass', ..., 'user_explicit_authorization', ..., 'action_is_destructive', ...]
REVIEW, not BLOCK. Nothing is wrong: changing stored data needs an
approval the agent cannot give itself, and on a fresh account nobody has given one. Two
things clear it. Attach a real signed approval from your own backend — see
Cryptographic human approval tokens for how to mint one —
and declare, for this action type, the two further facts a write leaves unobservable
(whether it is mass-scope, whether it is destructive; see
Declarations). With both in place the same
UPDATE returns ALLOW.
A destructive statement is different again. Whatever token you attach it stays
REVIEW — held, never run — because the rule wants a recent verified
backup, and that is a fact about your infrastructure rather than something the call can
carry. Nothing measured that backup, so the verdict names it rather than pretending it is
missing. Register a probe for it and your own backup system answers. If your agent should
never take an irreversible action at all, say so in the envelope
("structural_authority": {"irreversible": false}) and the statement
is BLOCK outright: a hard block comes from something observed against a
rule you set, never from a check nobody connected.
Two tests worth running before you trust any of this. First, a statement nothing can justify:
cert = az.verify(
action_type="execute_sql",
action_description="DROP TABLE users",
domain="database_ops"
)
print(cert.verdict) # REVIEW — held, it never runs; BLOCK once your envelope denies irreversible actions
Second — and this is the one that matters — have the agent claim an approval it does not have:
cert = az.verify(
action_type="execute_sql",
action_description="DELETE FROM users WHERE 1=1",
domain="database_ops",
agent_evidence={"production_explicit_authorization": True}, # the agent lies
)
print(cert.verdict) # BLOCK
print(cert.fabrication_detected) # True — the claim was caught and thrown out
A text filter has no way to run that second test, because there is nothing to compare the claim against. Every step on this page was re-run on 2026-09-16 on a fresh free-tier key, a free test key and an enterprise key: identical verdicts on all three.
There are three answers, so if not cert.block lets every REVIEW through.
Only cert.allow means cleared.
# Wrong — a REVIEW falls through and the action runs. if not cert.block: run(action) # Right — only a yes reaches the real work. if cert.allow: run(action) elif cert.review: ask_a_person(cert.summary) else: raise RuntimeError(cert.summary)
Arcezia acts as a runtime gate in front of your tool executions. Your models, prompts, and database tools remain unchanged.
Arcezia resolves safety into three distinct outcomes. Understanding REVIEW is fundamental: it represents a fail-safe hold when facts are unresolved.
| Verdict | State | Operational Meaning |
|---|---|---|
| ALLOW | Cleared | Every required safety precondition is grounded True. Tool execution proceeds. A single-use cert.credential is issued. |
| REVIEW | Unresolved (Fail-Safe) | A required precondition is ungrounded or unknown (e.g. backup status unverified). The action halts pending evidence or human intervention. |
| BLOCK | Denied | A mandatory constraint evaluated False, the action exceeded the session scope envelope, or fabricated claims were detected. |
Always Gate Positively on cert.allow: Never check if not cert.block. A REVIEW verdict is neither ALLOW nor BLOCK; testing only against BLOCK would allow unverified actions to execute.
| Field | Type | Description |
|---|---|---|
cert.allow | bool | True only when all required preconditions are satisfied. |
cert.review | bool | True when unresolved facts require evidence or human review. |
cert.block | bool | True when safety policies or scope are violated. |
cert.precondition_score | float [0.0..1.0] | Fraction of required domain preconditions satisfied. (On raw HTTP wire as precondition_score, alias dc_score). |
cert.trust_score | float [0.0..1.0] | Fraction of evidence verified via authoritative external sources vs model assertion. |
cert.credential | string | None | Cryptographic single-use token issued exclusively on ALLOW. |
cert.degraded | bool | True if Arcezia Cloud was unreachable and client fell back to synthetic verdict. Never carries a credential. |
cert.constraints | list[dict] | Detailed per-constraint quality status (GROUNDED, INFERRED, CLAIMED, UNRESOLVED, FABRICATED). |
Arcezia evaluates evidence according to strict provenance. An agent's self-generated text cannot satisfy structural requirements.
CLAIMED. If an LLM attempts to claim human authorization in its text, Arcezia marks the fact FABRICATED and returns BLOCK.Two External Facts That Cannot Be Read From Action Text:
• Environment Detection: Arcezia determines environment from ENVIRONMENT, ENV, or DATABASE_URL. If none are set, it defaults safely to production. Setting ENVIRONMENT=staging on your service enables staging rules; writing "staging" in action text changes nothing.
• Bulk Email Unsubscribe Links: For email_ops, unsubscribe_link_present must be grounded by a probe webhook connected to your mail provider or template engine.
Comprehensive runtime protection across individual tools, memory, workflows, and post-execution audits.
Checks destructiveness, parameter scope, authorization, and reversibility before any tool executes.
Maintains an immutable session record of previous mutations so later steps inherit accumulated state.
Evaluates multi-step plans in advance to catch exfiltration or destructive cascades before step 1 runs.
Compares actual side-effects (e.g. rows affected) against authorized limits to detect deviations.
Integrate Arcezia into any agent stack with one-line tool wrapping.
# 1. LangChain / LangGraph from arcezia.integrations.langchain import ArceziaToolkit safe_tools = ArceziaToolkit(az).wrap([sql_tool, bash_tool], domain_overrides={"sql_tool": "database_ops"}) # For LangGraph tool-calling nodes: safe_graph_tools = ArceziaToolkit(az).wrap_for_langgraph([sql_tool, bash_tool]) # 2. OpenAI Function Calling (name is positional and first) from arcezia.integrations.openai import ArceziaGuard safe_db = ArceziaGuard(az).wrap_function("execute_sql", db.execute, domain="database_ops") # 3. Anthropic Tool Use Filtering from arcezia.integrations.anthropic import ArceziaAnthropicGuard safe_uses, blocked = ArceziaAnthropicGuard(az).filter_tool_uses(message.content) for tool_call in safe_uses: execute(tool_call) # 4. LlamaIndex from llama_index.core.tools import FunctionTool from arcezia.integrations.llamaindex import guard_tool safe_tool = guard_tool(FunctionTool.from_defaults(fn=run_sql), az, domain="database_ops") # 5. AutoGen (0.2 & 0.4+) from arcezia.integrations.autogen import ArceziaAutoGenGuard safe_sql = ArceziaAutoGenGuard(az).wrap("execute_sql", db.execute, domain="database_ops") # 6. OpenCLAW (Dispatch loop) from arcezia.integrations.openclaw import DispatchGuard safe_dispatch = DispatchGuard(az).wrap(dispatch) # 7. Universal Callable (Pydantic AI, smolagents, Custom Loops) from arcezia import guard_callable safe_fn = guard_callable(my_function, az, action_type="send_invoice", domain="payment_ops") # 8. Claude Code Hook # Run from terminal: $ arcezia-hook install # 9. n8n (HTTP Node) # Use Header: Authorization: Bearer ar_live_... # Read verdict from $json.verdict and score from $json.precondition_score
CRITICAL Tool-Name Scope Gotcha: The wrapper passes the tool's actual definition name as action_type (e.g. wrapping sql_tool checks action_type="sql_tool", not "execute_sql"). Ensure your capability envelope lists the exact function names you wrap in allowed_action_types, or action_within_task_scope will ground False and BLOCK.
Chaining Helpers Disallowed on Wrapped Tools: Calling .bind(), .with_config(), .map(), .pipe(), .with_retry() on a wrapped tool raises AttributeError by design. These methods create new unwrapped objects that bypass safety checks. Always apply chaining helpers to your tool before wrapping, or use wrap_for_langgraph().
A SAFE chain hands each tool a credential. Every ALLOW step carries its own single-use credential, bound to that step’s action_identity.digest; a step’s credential is refused for any other step (action_digest_mismatch). When a credential is withheld, the step says why in credential_withheld. A SAFE chain with no credentials is a chain you may not run.
Inspect multi-action workflows to detect danger sequences before executing any individual step.
plan_manifest = { "steps": [ { "id": "read_ssn", "action_type": "execute_sql", "action_description": "SELECT ssn, name FROM customer_pii WHERE id = 101", "domain": "database_ops" }, { "id": "post_external", "action_type": "http_post", "action_description": "POST payload to https://external-analytics.com/dump", "domain": "api_ops" } ] } result = az.verify_chain(plan_manifest, stop_on_block=True) if result["overall_verdict"] == "SEMANTIC_BLOCK": print(f"Plan blocked at step: {result['blocked_at']}") print(f"Trigger: {result['semantic_triggers']}") # Output: Semantic block: Data Exfiltration sequence detected
How to build, secure, and deploy dynamic probe endpoints on your infrastructure to answer evidence checks in real time.
Register your probe webhook once using your API key. You can register a single dynamic router endpoint across multiple constraints:
curl -X POST https://api.arcezia.com/v1/probes \ -H "Authorization: Bearer ar_live_..." \ -H "Content-Type: application/json" \ -d '{ "domain": "database_ops", "constraint_name": "verified_recent_backup", "webhook_url": "https://ops.yourdomain.com/api/arcezia-probe", "secret": "your_secure_shared_secret_min16chars" }' # Returns: created (bool), dispatch_readback ("confirmed"), signing_key_v2
Registration Notes: Registration is idempotent; re-registering re-arms the probe. If registration returns HTTP 500 registration_not_visible, retry immediately. The webhook host must resolve in public DNS at registration and must not point at loopback, private, link-local or cloud-metadata addresses in any encoding (the resolved address is re-checked and pinned at call time). The webhook endpoint must be publicly accessible via HTTPS (use ngrok/cloudflared for local testing) and answer within 5 seconds.
When resolving a constraint, Arcezia POSTs a signed JSON payload to your webhook:
| Field | Type | Description |
|---|---|---|
domain | string | Target domain (e.g. "database_ops", "payment_ops"). |
constraint | string | Name of the constraint to ground (e.g. "verified_recent_backup"). |
action_type | string | Name of the tool being gated (e.g. "execute_sql"). |
parameters | dict | null | Structured scalar identifiers forwarded from tool arguments (record IDs, table names; max 32 entries). Always use these for lookups. |
untrusted_fields | list[str] | Lists agent-authored fields (e.g. ["action_description"]). Do NOT use for SQL templating or model prompt injection. |
import hmac, hashlib, os, datetime from fastapi import FastAPI, Request, HTTPException, status app = FastAPI(title="Arcezia Dynamic Probe Handler") SIGNING_KEY_V2 = os.getenv("ARCEZIA_SIGNING_KEY_V2", "your_signing_key_v2") # 1. Signature Verification Helper (Raw Body HMAC-SHA256) async def verify_arcezia_signature(request: Request, raw_body: bytes): sig_header = request.headers.get("X-Arcezia-Signature-V2") if not sig_header: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing signature header") expected_sig = hmac.new( SIGNING_KEY_V2.encode("utf-8"), raw_body, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(f"sha256={expected_sig}", sig_header): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid signature") # 2. Dynamic Handlers (Lookup via parameters map) def check_verified_recent_backup(params: dict) -> tuple[bool, str]: last_backup_time = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(hours=1) is_valid = (datetime.datetime.now(datetime.timezone.utc) - last_backup_time).total_seconds() < 86400 return is_valid, f"Latest snapshot verified at {last_backup_time.isoformat()}" def check_aml_passed(params: dict) -> tuple[bool, str]: recipient_id = params.get("recipient_id") if params else None if not recipient_id: return False, "Missing recipient_id in action parameters" return True, f"Recipient {recipient_id} cleared OFAC/AML screening" PROBE_DISPATCH_TABLE = { ("database_ops", "verified_recent_backup"): check_verified_recent_backup, ("payment_ops", "aml_check_passed"): check_aml_passed, } # 3. Dynamic Webhook Endpoint @app.post("/api/arcezia-probe") async def handle_probe_webhook(request: Request): raw_body = await request.body() await verify_arcezia_signature(request, raw_body) payload = await request.json() domain = payload.get("domain") constraint = payload.get("constraint") parameters = payload.get("parameters") or {} handler = PROBE_DISPATCH_TABLE.get((domain, constraint)) if not handler: return { "value": False, "grounded": False, "detail": f"No handler for {constraint}" } try: is_satisfied, detail_msg = handler(parameters) return { "value": is_satisfied, "grounded": True, "detail": detail_msg } except Exception as err: return { "value": False, "grounded": False, "detail": f"Error: {str(err)}" }
const crypto = require('crypto'); const express = require('express'); const app = express(); // Capture raw body for exact HMAC-SHA256 signature verification app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } })); const SIGNING_KEY_V2 = process.env.ARCEZIA_SIGNING_KEY_V2; app.post('/api/arcezia-probe', (req, res) => { const sigHeader = req.headers['x-arcezia-signature-v2']; const computed = crypto.createHmac('sha256', SIGNING_KEY_V2) .update(req.rawBody) .digest('hex'); if (!sigHeader || !crypto.timingSafeEqual(Buffer.from(`sha256=${computed}`), Buffer.from(sigHeader))) { return res.status(401).json({ error: 'Invalid signature' }); } const { domain, constraint, parameters } = req.body; if (domain === 'database_ops' && constraint === 'verified_recent_backup') { return res.json({ value: true, grounded: true, detail: 'Postgres pg_dump confirmed within 2 hours' }); } return res.json({ value: false, grounded: false, detail: 'Constraint unhandled' }); });
Allow high-risk operations (such as production drops or high-value transfers) to proceed with cryptographic proof of human approval.
curl -X POST https://api.arcezia.com/v1/account/token_key \ -H "Authorization: Bearer ar_live_..." \ -H "Content-Type: application/json" \ -d '{ "public_key": "<base64url-of-32-byte-ed25519-public-key>" }'
When an admin confirms an action in your web UI, your backend mints a signed token (max 15-minute TTL):
# Token Format: base64url(payload_json) + "." + base64url(ed25519_signature) # The signature is over the ASCII bytes of the base64url payload segment. { "acct": 26, # your numeric key id (Keys page; task_manifest.api_key_id on /v1/session) "sid": "session_id_from_az", "typ": "production", # or "user" — must equal the token_type you attach it as "exp": 1724836000, # integer, at most 15 minutes ahead "jti": "unique_single_use_token_id", # single use; a second presentation is refused "act": "<action_binding from the verdict>" # optional: binds the approval to that one exact call }
Every verdict carries an action_binding — one value for that exact
call: tool, domain, statement and typed arguments. Put it in act and the
approval covers that call and no other; the same tool with different arguments stays held.
Leave act out and the approval is session-wide.
# Attach the human approval tokens to the session (typ "user" and, for a # production target, typ "production") az.authorize(signed_user_token) az.authorize_production(signed_production_token) # Re-verify the action cert = az.verify( action_type="execute_sql", action_description="UPDATE customers SET tier='pro' WHERE id = 42", domain="database_ops" ) if cert.allow: db.execute(...) # Cleared by verified human signature
A token clears a write, not a destructive statement. A
DELETE or DROP stays BLOCK
with whatever token is attached until a registered probe answers that a recent, verified
backup exists (Dynamic webhook handlers).
Guard against unintended blast radius before and after execution.
Register a simulation sandbox (POST /v1/simulate/register) to dry-run queries before gating:
def simulate_database_action(req): # Dry-run inside a rolled-back transaction with db.transaction() as tx: cursor = tx.execute(req.json["action_description"]) rows = cursor.rowcount tx.rollback() # CRITICAL: rowcount is -1 for DDL (DROP/ALTER/TRUNCATE) in Python DB-API if rows is None or rows < 0: return { "acceptable": False, "reason": "Unmeasured DDL mutation (DROP/ALTER)" } return { "acceptable": rows <= 1000, "reason": f"{rows} rows touched", "outcome": { "rows_affected": rows } }
audit = az.verify_outcome(
action_type="execute_sql",
action_description="Prune analytics",
outcome={"rows_affected": 125000}, # Real consequence
expected={"rows_affected": 500} # Authorized scope
)
if audit.block:
alert_security_team(f"Anomaly detected: {audit.violations}")
Set hard architectural ceilings for each session using signed capability envelopes.
az.start_session(capability_envelope={
"allowed_domains": ["database_ops"],
"allowed_action_types": ["execute_sql"],
"max_scope": "limited", # single_record=1 | batch=100 | limited=1000 | mass=unlimited
"structural_authority": {
"sensitive_data": False,
"persistent_mutation": True, # NOT "mutation"
"mass_scope": False,
"outbound": False,
"trust_boundary_crossing": False, # NOT "trust_crossing"
"irreversible": True # DELETE/DROP requires True
}
})
| Axis | Meaning | When set to False (Hard Ceiling) |
|---|---|---|
sensitive_data | PII, credentials, or confidential fields | Blocks queries touching sensitive tables/columns. |
persistent_mutation | Permanent state modifications | Enforces read-only operation. |
mass_scope | Bulk or unbounded operations | Caps operations at single/batch thresholds. |
outbound | Network egress or external transmission | Blocks external webhook or email dispatch. |
trust_boundary_crossing | Transfers between security tiers | Blocks exporting internal data to client-facing nodes. |
irreversible | Operations without undo paths | Blocks destructive commands (DELETE, DROP). Setting this False means no approval token can lift it. |
Envelope Gotchas:
• Listing Action Types: Omitting allowed_action_types is permissive within allowed domains. An empty list [] permits nothing and BLOCKs all actions.
• Setting False is a Hard Ceiling: An axis set to False can never reach ALLOW, even with a human approval token. To allow escalation, omit the axis from the envelope instead of setting it False.
Complete lookup matrix of all 18 built-in domains to their required preconditions and resolution channels.
| Domain | Preconditions Required for ALLOW | Grounding Channel |
|---|---|---|
| database_ops | action_within_task_scopeproduction_explicit_authorizationverified_recent_backuptarget_object_existscascade_effects_verified | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook |
| payment_ops | action_within_task_scopeuser_explicit_authorizationpayment_recipient_verifiedaml_check_passedsanctioned_entity_check_passed | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook |
| filesystem_ops | action_within_task_scopeuser_explicit_authorizationrecent_backup_existssecret_scan_passedtarget_outside_critical_pathstarget_under_version_controlworking_tree_clean | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| cloud_ops | action_within_task_scopeuser_explicit_authorizationbackup_existsresource_has_deletion_protection | Envelope Signed Token Probe Webhook Probe Webhook |
| deployment_ops | action_within_task_scopeuser_explicit_authorizationtests_passedrollback_plan_existsrequired_reviewers_approvedconfig_drift_assessed | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| email_ops | action_within_task_scopeuser_explicit_authorizationrecipient_is_opted_inrecipient_not_on_suppression_listattachment_scannedunsubscribe_link_present | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| messaging_ops | action_within_task_scopeuser_explicit_authorizationattachment_scanned | Envelope Signed Token Probe Webhook |
| crm_ops | action_within_task_scopeuser_explicit_authorizationcontact_consent_verifiedaccess_logged | Envelope Signed Token Probe Webhook Probe Webhook |
| data_warehouse_ops | action_within_task_scopeuser_explicit_authorizationbackup_or_snapshot_existsdata_governance_policy_metresult_anonymized | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook |
| api_ops | action_within_task_scopeuser_explicit_authorization | Envelope Signed Token |
| browser_ops | action_within_task_scopeuser_explicit_authorizationtarget_url_is_whitelisted | Envelope Signed Token Probe Webhook |
| agent_action | action_within_task_scopeuser_explicit_authorizationbudget_or_rate_within_limits | Envelope Signed Token Probe Webhook |
| customer_support | action_within_task_scopeuser_explicit_authorization | Envelope Signed Token |
| pii_ops | action_within_task_scopedata_subject_consent_verifieduser_explicit_authorizationaccess_loggedadequacy_decision_or_safeguards_presentlegal_basis_established | Envelope Signed Token Signed Token Probe Webhook Probe Webhook Probe Webhook |
| healthcare_ops | action_within_task_scopephi_access_authorizeduser_explicit_authorizationaudit_log_enabledbaa_in_placedata_encrypted_at_restdata_encrypted_in_transitpatient_consent_verified | Envelope Signed Token Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| financial_compliance | action_within_task_scopeuser_explicit_authorizationaml_check_passedkyc_verifiedsanctioned_entity_check_passedaudit_trail_maintained | Envelope Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| eu_ai_act | action_within_task_scopehuman_oversight_maintaineduser_explicit_authorizationaccuracy_robustness_verifiedbias_audit_passedconformity_assessment_completedata_bias_examineddata_quality_assesseddata_representativeness_verifiedtraining_data_documentedtransparency_disclosure_made | Envelope Signed Token Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
| government_ops | action_within_task_scopemulti_party_authorizationuser_explicit_authorizationaudit_trail_maintainedneed_to_know_establishedsecurity_clearance_sufficientsystem_accreditation_valid | Envelope Signed Token Signed Token Probe Webhook Probe Webhook Probe Webhook Probe Webhook |
on_error Mode | Behavior on Network Partition | Security Profile |
|---|---|---|
"fail_closed" (Default) | Raises ArceziaUnavailableError. Tool execution is halted. | Recommended for production environments. |
"review" | Returns synthetic REVIEW (cert.degraded = True). | Safe degradation; routes action to human review. |
"fail_open" | Returns synthetic ALLOW (cert.degraded = True). | Permissive fallback; only for non-critical logging. |
from arcezia.exceptions import ArceziaRateLimitError try: cert = az.verify(...) except ArceziaRateLimitError as exc: if exc.retry_after: time.sleep(exc.retry_after) # Per-minute burst limit (retry after seconds) else: raise RuntimeError("API verification quota reached. Contact administrator.")
If an action returns REVIEW unexpectedly, check two things:
cert.constraints: Find constraints marked UNRESOLVED. Look up their grounding channel in Section 11.cert.probe_outcomes: Compares registered probes against outcomes (answered, declined, unreachable, rejected, malformed). If a registered probe is absent from probe_outcomes, re-register it via POST /v1/probes."run_cleanup('temp')" default to REVIEW because state mutation cannot be statically determined. Name actions concretely: "delete temp files older than 30 days from ./build".cert = az.verify(...) if cert.review: print(f"Review Reason: {cert.summary}") for c in cert.constraints: if c["quality"] == "UNRESOLVED": print(f"→ Missing ungrounded fact: {c['name']}")