> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heretic.quest/llms.txt
> Use this file to discover all available pages before exploring further.

# Enforce Traffic Policy Using Heretic Verdicts and Signals

> Translate Heretic verdicts into block, challenge, or allow decisions. Best practices for enforcement logic keyed on signal IDs and evidence families.

Heretic provides the ruling and the evidence; what you do with it is entirely up to you. Heretic never blocks traffic on your behalf — it hands your application a structured verdict and a list of signals, and your code decides whether to block, challenge, flag for review, or pass the request through. This separation keeps enforcement logic in your control and makes it auditable, version-controlled, and easy to tune over time.

## Decision Framework

The table below maps each verdict and `conclusive` value to a recommended enforcement action. Treat this as a starting point; adjust thresholds to match your product's risk tolerance.

| Verdict          | `conclusive` | Recommended Action                                                                                 |
| ---------------- | ------------ | -------------------------------------------------------------------------------------------------- |
| `contradicted`   | `true`       | **Block or hard challenge** — evidence is absolute or composite-corroborated. Act with confidence. |
| `contradicted`   | `false`      | **Soft challenge** — direction is clear but evidence hasn't reached the conclusive bar yet.        |
| `refused`        | —            | **Challenge or block** — the browser withheld data. Treat as suspicious by default.                |
| `disputed`       | —            | **Monitor or soft challenge** — inconsistencies exist but no clean contradiction. Log and watch.   |
| `uncontradicted` | —            | **Allow** — no contradictions detected.                                                            |
| `insufficient`   | —            | **Allow or low-friction challenge** — too little data to rule. Avoid hard blocking.                |

## Middleware Example

The pattern below shows a minimal Express.js middleware that reads the session ID from a request header, fetches the verdict, and blocks on a conclusive contradiction. All other sessions continue through the middleware chain with the verdict attached to the request for downstream handlers.

```ts theme={null}
import express from 'express';

const app = express();

async function fetchVerdict(sessionId: string) {
  const res = await fetch(
    `https://edge.heretic.quest/e?n=${sessionId}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.HERETIC_API_KEY}`,
      },
    }
  );
  if (!res.ok) return null; // treat fetch errors as non-blocking
  return res.json();
}

app.use(async (req, res, next) => {
  const sessionId = req.headers['x-heretic-session'];

  // No session header — pass through and let downstream logic decide.
  if (!sessionId) return next();

  const verdict = await fetchVerdict(sessionId as string);

  // Hard block: conclusive contradiction.
  if (verdict?.verdict === 'contradicted' && verdict?.conclusive) {
    return res.status(403).json({ error: 'Access denied' });
  }

  // Attach the verdict for downstream handlers to inspect.
  (req as any).hereticVerdict = verdict;
  next();
});
```

<Tip>
  Keep the `fetchVerdict` call non-blocking for error cases (`if (!res.ok) return null`). If the Heretic endpoint is temporarily unreachable, fail open rather than blocking legitimate traffic.
</Tip>

## Keying Policy on Signal IDs

Signal IDs like `geo.rtt-below-vacuum` and `stack.os-contradiction` are **stable across releases**. That means you can hard-code them in your policy rules and rely on them not changing between Heretic versions.

Use this to build granular rules rather than acting only on the top-level verdict. For example:

```ts theme={null}
// Guard: verdict may be null if the explain endpoint was unreachable.
if (!verdict) return next();

const isContradicted = verdict.verdict === 'contradicted';

const geoContradiction =
  isContradicted &&
  verdict.contradicting_families.includes('network-geometry');

const stackContradiction =
  isContradicted &&
  verdict.contradicting_families.includes('transport-stack');

if (geoContradiction && verdict.conclusive) {
  // Show a regional restriction message rather than a generic block page.
  return res.status(403).json({
    error: 'Service not available in your region',
    code: 'GEO_RESTRICTION',
  });
}

if (stackContradiction && verdict.conclusive) {
  // OS/transport contradiction — challenge with CAPTCHA.
  return res.status(403).json({ error: 'Verification required', code: 'CHALLENGE' });
}
```

Signal IDs are dot-namespaced by family (`geo.*`, `stack.*`, `render.*`, etc.), so a `startsWith` filter gives you family-level granularity without enumerating every individual ID.

<Tip>
  `contradicting_families` tells you at a glance which families fired. Use it in your UI layer — for example, if `contradicting_families` includes `network-geometry`, surface a regional restriction notice rather than a generic "access denied" message. Specific messaging reduces support tickets.
</Tip>

## What Not to Do

<Warning>
  **Do not block on `insufficient` alone.** Some legitimate visitors — those behind strict corporate proxies, certain mobile carriers, or privacy-hardened browsers — naturally produce fewer measurable signal families. An `insufficient` verdict means Heretic couldn't gather enough data to rule, not that the visitor is malicious. Apply only low-friction challenges (if anything) to these sessions.
</Warning>

<Warning>
  **Do not call the explain endpoint more than once per session ID.** Session IDs are single-use from a rate-limit perspective. Cache the verdict in your session store and reuse it for the lifetime of the user's session rather than re-fetching on every request.
</Warning>


## Related topics

- [Signal Tiers, Ruling Algebra, and Enforcement Policy](/concepts/signal-tiers.md)
- [Heretic API Keys: Collector Setup and Explain Endpoint](/dashboard/api-keys.md)
- [Heretic Pricing: Apostate, Heretic, and Inquisition Tiers](/reference/pricing.md)
- [Heretic FAQ: Integration, Verdicts, Privacy, and Access](/reference/faq.md)
- [Heretic Signal Reference: IDs, Evidence Families, and Tiers](/reference/signals.md)
