How Rules Work
Rules define what context your agents are permitted to see. Every document or tool result captured by the in-process SDK is evaluated against your rule set. Rules compile into a bundle that SDKs download and cache locally — evaluation happens in-process, with no network round-trip on the retrieval hot path. There is one rule engine for action and retrieval governance: a rule is a single object tagged with the operations it targets (operations[] — action, retrieval, or both), and the same rule source evaluates identically on the server and inside the SDK. Rules created through the retrieval endpoints are tagged retrieval automatically; the dashboard rule editor can tag one rule with both operations so a single policy governs a hybrid read-write tool.
Evaluation is a priority-descending, first-match-wins cascade: rules are sorted by priority (highest number first) and the first rule whose checks and conditions match decides the outcome.
Rule Structure
A rule has the following fields:Example Rule (JSON)
Trust Tiers and Need-to-Know
Each agent is assigned a trust tier by an operator, and (separately) a business function classified automatically from what the agent does — you can pin it by hand. Both are server-authoritative: rules read them asinput.agent.trust_tier and input.agent.business_function, and a caller cannot spoof them.
The default protection every tenant ships with is a curated catalog of 35 default rules built on a need-to-know matrix: for each protected data category, the outcome combines whether the agent’s business function needs that category with its trust tier —
- Need +
tier1→ full value - Need +
tier2→ escalate for human review (redact for the highest-volume categories) - Need +
tier3→ masked - No need-to-know → masked, or denied for the most sensitive classes
- Missing/unknown attributes → falls into a protective branch (fail-closed)
Document Classifications
Rules gate on the metadata your documents carry — most commonlyresource_metadata.classification (a sensitivity level: public, internal, confidential, restricted) and resource_metadata.data_categories (content tags such as pii, pci, financial, credentials).
Surfaces
Surfaces represent the communication channel where the agent’s output will be delivered. Rules can restrict context based on the destination surface — a document might be allowed in a private group but denied in a public channel.
A rule with
surface: "PUBLIC_CHANNEL" applies only when the agent’s output surface is a public channel; on other surfaces the cascade skips it. Rules without a surface restriction match all surfaces.
Policy Format
Every rule’srego_source is a policy in a supported subset of Rego, interpreted by the same evaluator on the server and in the SDK — a rule decided one way on the server is decided identically in-process.
Input Document
The evaluation input has these fields:Supported Conditions
Constructs outside the subset (
some iterators, comprehensions, custom functions, cross-field comparisons) are not supported. A condition the engine cannot parse becomes always-false — the rule can never match (fail-closed) — and both the dashboard editor and the AI compiler reject non-evaluable conditions before saving.
Decisions
The decision response also carries a machine
reason_code (TIER_MISMATCH, PRINCIPAL_EXCLUDED, POLICY_DENY, AUDIENCE_EXPANSION, SURFACE_RESTRICTION, POLICY_ALLOW, DEFAULT_DENY, EMERGENCY_BYPASS, and MONITOR_MODE — recorded when a monitor-mode agent’s would-be decision is overridden to allow) derived by the engine — you do not author reason codes in the policy.
Example: Surface-Based Restriction
Masking (redaction_spec)
A redact decision applies the rule’s masking directives. Each directive names a structured field to mask wherever it appears and/or a regex pattern applied to string content, plus a masking mode — surfaced in the rule editor as:
Masking is authored per decision branch: each
redact branch of a rule carries its own set of directives, so one rule can mask account numbers on its medium-trust branch and everything on its low-trust branch. A rule supports up to 50 directives and 50 masking branches.
Masking is fail-closed end to end: a redact decision whose directives cannot be resolved is denied when the rule opts into fail-closed behavior, and if applying a mask throws at runtime, the SDK excludes the document rather than leaking it unredacted.
Natural Language Rules
You can describe rules in plain English. Retrieval governance compiles them to policy using AI (thePOST /recall/rules/compile endpoint, rate-limited to 10 requests per minute per organization). No policy-language expertise required.
Example prompt: “Deny tier3 agents from accessing any document classified as internal, confidential, or restricted.”
The compiler reads your existing rules for context, validates that every condition is evaluable by the engine, and can save the rule directly. The dashboard rule editor offers the same NL-first authoring plus a visual condition builder and a Simulate panel that replays your rule against recent real traffic before you save.
Rules authored in the dashboard also pass a simulated-interference gate: a rule that would deny or escalate more than 5% of your recent real traffic is rejected (INTERFERENCE_THRESHOLD_EXCEEDED) until you make it more specific. Masking never counts as interference — a masked request still proceeds.
Rule Evaluation Flow
When a retrieved document is evaluated, the engine walks rules from highest priority down. For each rule:- Emergency bypass — a rule under an active emergency bypass returns
allow(EMERGENCY_BYPASS) immediately. - Principal exclusions — an agent listed in the rule’s
principal_exclusionsis denied (PRINCIPAL_EXCLUDED). - Surface restriction — a surface-scoped rule applies only when the input surface matches; otherwise the cascade skips it.
- Trust tier — a rule with
trust_tierset denies agents below that tier (TIER_MISMATCH). - Policy conditions — the rule’s
rego_sourceis evaluated; if a decision block matches, its decision is final. For rules without a surface restriction, a non-matching body falls through to the next rule — but a surface-scoped rule whose surface matches is always decisive: a non-allow body resolves toSURFACE_RESTRICTIONrather than falling through.
default decision declaration never decides the event, so per-rule defaults are inert and the cascade continues. When no rule matches at all, the decision is deny (DEFAULT_DENY, fail-closed).
The SDK evaluates the same cascade in-process against its cached bundle (GET /rules/bundle, a SHA-256-versioned bundle with ETag/304 caching, refreshed in the background roughly every 5 seconds). With a VISIQ_API_KEY the harness reaches SaaS (https://api.visiqlabs.com by default) and confirms this bundle automatically — monitor-until-confirmed is only the brief pre-first-bundle window. On that cold start with no bundle loaded, an agent confirmed in enforce stays fail-closed, while a never-confirmed agent runs monitor; the no-match DEFAULT_DENY floor still applies wherever enforcement is active.
Managing Rules
Rules can be created and managed via:- Dashboard: Navigate to Harness → Rules at app.visiqlabs.com. The unified editor covers both action and retrieval rules — create manually, describe in natural language, or edit the visual condition graph.
- REST API: Use the rules endpoints documented in the API Reference for programmatic rule management, CI/CD pipelines, and bulk imports.