# What Is the Radar Free-Model Catalog Overlay in OmniRoute? How It Works and How to Configure It

> Discover the Radar free-model catalog overlay in OmniRoute. Learn how this real-time system provides updated quota feeds without altering static catalogs for improved budget management.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-08-19

---

**The Radar free-model catalog overlay is a read-time system that layers a cryptographically verified, remotely updated feed onto OmniRoute's static free-model budget catalog**, allowing users to receive real-time quota updates without modifying the shipped baseline.

OmniRoute's free-tier model budgets are baked into each release as the `FREE_MODEL_BUDGETS` constant. Because cloud provider quotas change faster than release cycles, the open-source routing framework implements Radar as an overlay rather than a replacement. This design preserves reproducible builds while delivering current pricing intelligence.

---

## How the Radar Free-Model Catalog Overlay Functions

Radar operates as a **three-layer stack**: a static baseline, a verified remote feed, and local user overrides. The system merges these layers at read time based on strict precedence rules.

### Feature Flag and Opt-In Requirements

Two gates must both open before any network activity occurs:

- **`RADAR_ENABLED`** — A boolean feature flag defined in [`src/shared/constants/featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/featureFlagDefinitions.ts) (default `false`). When disabled, all `/api/radar/*` routes return **404** and `getRadarCatalog()` returns the unmodified baseline catalog.

- **`radar_settings.opt_in`** — A per-user database flag managed by [`src/lib/db/radar.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/radar.ts). This privacy-preserving requirement ensures explicit consent before any external request.

These dual gates appear in migration [`136_radar_cache_settings.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/136_radar_cache_settings.sql), which creates the settings table with the `opt_in` column.

### Feed Synchronization and Verification

When both gates pass, the `syncRadar()` function in [`src/lib/radar/sync.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/sync.ts) executes:

```typescript
// Pseudocode based on actual implementation in src/lib/radar/sync.ts
async function syncRadar(): Promise<void> {
  const response = await fetch(`${RADAR_FEED_URL}/v1/catalog/latest`, {
    headers: supporterKey ? { "Authorization": `Bearer ${supporterKey}` } : {},
    // Size cap: 10 MiB
  });
  
  const bytes = await response.arrayBuffer();
  
  // Ed25519 signature verification before any parsing
  verifyFeedBytes(bytes, pinnedPublicKey);
  
  // Schema validation against RadarFeedSchema
  const feed = parseAndValidate(bytes);
  
  // Cache for read-time merge
  await updateRadarCache(feed);
}

```

The feed carries an **Ed25519 signature** verified against pinned keys in [`src/lib/radar/pinnedKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/pinnedKeys.ts). Forks can override either the feed URL (`RADAR_FEED_URL`) or the public key (`RADAR_FEED_PUBKEY`). The signature is checked against raw bytes before JSON parsing, preventing signature-stripping attacks.

### Read-Time Merge Rules

The `applyFeed()` function in [`src/lib/radar/applyFeed.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/applyFeed.ts) implements four precedence rules on each `getRadarCatalog()` call:

1. **Local overrides win** — User-modified display names or enabled flags in `radar_local_model_state` take top priority
2. **Feed-disabled entries add metadata** — Entries disabled upstream receive `disabledBy: "radar"` in the response
3. **Locally added entries survive** — Custom models created by the user persist through feed updates
4. **Tombstoned entries never resurrect** — Explicitly removed models stay hidden regardless of feed contents

This merge is **non-destructive**: the static baseline and cached feed remain unchanged on disk.

### Local Override Persistence

User customizations store in `radar_local_model_state` (migration [`153_radar_local_model_state.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/153_radar_local_model_state.sql)). The [`src/lib/db/radar.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/radar.ts) module provides CRUD operations for:

- Display name overrides
- Enabled/disabled toggles  
- Tombstone records for hidden models

These surfaces are **never proxies to the feed** — they exist purely in local SQLite storage.

---

## Community vs. Live Feed Tiers

The Radar feed distinguishes access levels through the **`x-omniroute-feed-tier`** response header:

| Tier | Characteristic | Use Case |
|------|---------------|----------|
| **Community** | 30-day delayed snapshot | Free, unauthenticated users |
| **Live** | Real-time quota data | Supporter key holders (`omr_` prefix) |

The response body always contains `tier: "live"`, but the header is authoritative. The `parseServedTierHeader()` function in [`src/lib/radar/sync.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/sync.ts) handles this distinction.

---

## Practical Configuration Example

Enable and activate the Radar free-model catalog overlay:

```typescript
// Step 1: Enable feature flag (environment or config)
process.env.RADAR_ENABLED = "true";

// Step 2: Opt-in via API (requires authentication)
await fetch("/api/radar/settings", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ 
    optIn: true, 
    supporterKey: "omr_0123...abcd"  // Optional, unlocks Live tier
  }),
});

// Step 3: Trigger synchronization
await fetch("/api/radar/sync", { method: "POST" });

// Step 4: Consume merged catalog
const response = await fetch("/api/radar/catalog");
const catalog = await response.json();
// Entries contain: origin ('baseline' | 'feed' | 'local'), disabledBy?, userOverrides?

```

All endpoints reside in `src/app/api/radar/` and enforce the flag/opt-in checks before any external communication.

---

## Security Architecture

Radar's security model centers on **offline-verifiable trust**:

- **Pinned public keys** in [`src/lib/radar/pinnedKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/pinnedKeys.ts) — Hardcoded Ed25519 keys that can rotate via environment overrides
- **Byte-level signature verification** — `verifyFeedBytes()` operates on raw response bytes, not parsed JSON
- **Size caps** — 10 MiB maximum feed size prevents memory exhaustion
- **Schema validation** — `RadarFeedSchema` rejects malformed entries before merge

The [`supporterKey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/supporterKey.ts) module validates `omr_` prefix format and masks keys in API responses to prevent accidental exposure.

---

## Key Source Files

| Path | Responsibility |
|------|---------------|
| [`src/lib/radar/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/index.ts) | Public API: `getRadarCatalog()` entry point |
| [`src/lib/radar/sync.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/sync.ts) | Network fetch, Ed25519 verification, caching |
| [`src/lib/radar/applyFeed.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/applyFeed.ts) | Four-rule read-time merge implementation |
| [`src/lib/radar/pinnedKeys.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/pinnedKeys.ts) | Built-in public keys and override support |
| [`src/lib/radar/supporterKey.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/supporterKey.ts) | Key format validation and masking |
| [`src/lib/db/radar.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/radar.ts) | Database operations for settings and overrides |
| `src/app/api/radar/` | HTTP route handlers (catalog, sync, settings, etc.) |
| [`src/shared/constants/featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/featureFlagDefinitions.ts) | `RADAR_ENABLED` flag definition |
| [`src/lib/db/migrations/136_radar_cache_settings.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/migrations/136_radar_cache_settings.sql) | Settings table with `opt_in` column |
| [`src/lib/db/migrations/153_radar_local_model_state.sql`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/migrations/153_radar_local_model_state.sql) | Override and tombstone storage |
| [`docs/frameworks/RADAR.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/frameworks/RADAR.md) | Canonical design documentation |

---

## Summary

- **Radar overlays** a signed remote feed onto OmniRoute's static free-model catalog without modifying the baseline
- **Dual gates** (`RADAR_ENABLED` flag + `opt_in` setting) control all network activity
- **Ed25519 signatures** and pinned keys ensure feed authenticity before any parsing
- **Four merge rules** resolve conflicts between baseline, feed, and local user overrides at read time
- **Two tiers** (Community 30-day delay vs. Live real-time) serve different user needs
- **Local state persistence** for overrides and tombstones lives entirely in SQLite, never proxied to external services

---

## Frequently Asked Questions

### How do I completely disable Radar in OmniRoute?

Set `RADAR_ENABLED=false` (the default) in your environment or configuration. All `/api/radar/*` endpoints will return 404, and `getRadarCatalog()` returns only the static `FREE_MODEL_BUDGETS` baseline. No opt-in or network code executes.

### Can I run Radar without a supporter key?

Yes. Without a key, you receive the **Community tier** — a 30-day delayed snapshot of free-model budgets. The feed URL remains the same; the server determines tier by authentication header presence and validity.

### What happens if the Radar feed signature fails verification?

`syncRadar()` aborts before caching any data. The previous cached feed (if any) continues to serve until expiration, or the baseline catalog alone serves if no cache exists. Signature failures are logged; administrators can inspect [`src/lib/radar/sync.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/radar/sync.ts) for verification details.

### Does Radar modify my local OmniRoute installation?

Never. The overlay is **read-time only**. Source files, the `FREE_MODEL_BUDGETS` constant, and any installed release artifacts remain unchanged. Only the `radar_local_model_state` table in your SQLite database holds user-specific overrides — and this stays locally scoped to your instance.