Intel is the evidence workspace for qai’s target-centric workflow. You pick a target, build evidence against it (import findings, probe the model, sweep document-context templates), review everything on the target’s detail page, and — once a sweep has produced usable findings — launch qai ipi generate with the recommended template straight from the page.
The entry point is the Intel nav item, which opens the target list landing at /intel. Each target has a detail page at /intel/targets/<target_id> that surfaces its evidence.
Target list landing
/intel is a list of targets. Each row shows the target’s name, type, URI, and age badges for its most recent probe run, sweep run, and import — in the 12d / 2h / 45m / now / — format. Click any row to open that target’s detail page.
Below the target list sit three launcher cards — Import Results, Probe Model, and Sweep. Use these to collect evidence for a target. Each launcher requires a target; no card runs against “no target” or offers an “optional” target field.
Targets themselves are managed via qai targets (add / list / delete) or created inline from any Intel launcher card. New targets do not have to exist before you click a launcher — the + Create new target option in the target selector opens a modal that creates the target and binds the launch to it in one step.
Inline target creation
Every launcher card’s Target selector offers:
- every existing target, and
- a
+ Create new target sentinel option at the top of the list.
Selecting the sentinel opens a shared modal. Submitting the modal calls POST /api/intel/targets/create, appends the new target to the selector, and binds the current launch to it. The modal closes on success; the launcher’s existing form values (endpoint, model, API key, etc.) are preserved.
Import Results card
Upload findings from external tools and benchmarks. Supported formats: Garak (JSONL), PyRIT (JSON), SARIF, scored-prompts (JSON), and BIPIA (CSV).
Fields
| Field | Required | Description |
|---|
| File | Yes | Findings file in one of the supported formats |
| Format | Yes | bipia, garak, pyrit, sarif, or scored |
| Target | Yes | Target to attach findings to — choose an existing target or + Create new target |
Workflow
- Choose a file and format.
- Pick the target (or create one inline).
- Preview — parses the file and shows a findings summary without writing to the database.
- Import — commits findings to the database and returns a run ID.
The preview step lets you verify what will be imported before committing. This mirrors the CLI’s --dry-run flag on qai import.
API endpoints
| Method | Path | Description |
|---|
| POST | /api/intel/import/preview | Parse the file, return findings summary — no DB write |
| POST | /api/intel/import/commit | Parse the file, persist to DB, return run ID |
Probe Model card
Runs the 20 built-in probes across 8 IPI categories against a target model using canary-based scoring. This is the Web UI equivalent of qai ipi probe.
Fields
| Field | Required | Description |
|---|
| Endpoint URL | Yes | OpenAI-compatible API base URL (e.g., http://localhost:8000/v1) |
| Model | Yes | Model name for chat completions |
| API Key | No | Sent as the X-API-Key request header to the qai probe endpoint — qai forwards it to the upstream provider as Authorization: Bearer. Not logged, not persisted |
| Temperature | No | Sampling temperature (default 0.0). Use 0.0 for reproducible probing. Higher values add randomness |
| Concurrency | No | Max parallel upstream requests (default 1). Raise to 4–8 on endpoints that tolerate concurrency |
| Target | Yes | Target to bind the probe run to — existing target or + Create new target |
Probe and Sweep launch endpoints accept the API key via the X-API-Key request header, not as a JSON body field. The form sends the value in that header automatically. Any api_key field found in the JSON body is silently ignored for backward compatibility.
Workflow
- Fill in endpoint and model.
- Pick or create the target.
- Launch Probes — probing runs as a background task. The browser navigates to the target’s detail page.
- When the run finishes, refresh the detail page to see it surface in Probe Runs.
API endpoint
| Method | Path | Description |
|---|
| POST | /api/intel/probe/launch | Launch probing as background task, returns 202 |
Sweep card
Measures per-template compliance against a target model. Sweep results feed the template recommendation that drives the Generate button on the target detail page and qai ipi generate --target. This is the Web UI equivalent of qai ipi sweep.
Fields
| Field | Required | Description |
|---|
| Endpoint URL | Yes | OpenAI-compatible API base URL |
| Model | Yes | Model name for chat completions |
| API Key | No | Sent as the X-API-Key request header to the qai sweep endpoint — qai forwards it to the upstream provider as Authorization: Bearer. In-memory only |
| Temperature | No | Default 0.0 |
| Concurrency | No | Default 1 |
| Reps | No | Repetitions per (template, style) pair — default 3 |
| Templates | Yes | Multi-select. All 12 document-context templates are selected by default. Ctrl/Cmd-click to deselect individual templates |
| Styles | Yes | Multi-select. All 7 payload styles are selected by default. Ctrl/Cmd-click to deselect |
| Target | Yes | Target to bind the sweep run to |
| Payload Type | — | Fixed to callback in v1 (sent as a hidden form field) |
Workflow
- Fill in endpoint and model.
- Adjust templates/styles/reps if you don’t want the defaults.
- Pick or create the target.
- Launch Sweep — the sweep runs as a fire-and-forget background task. The browser navigates to the target’s detail page.
- Refresh the detail page once the sweep finishes to see it surface in Sweep Runs and, if the findings are conclusive, enable the Generate button.
The launch response (202) does not include a run_id. The run row is created inside the background task after the sweep’s HTTP calls complete, which happens after the 202 is returned. Refresh the target detail page to pick up the completed run.
API endpoint
| Method | Path | Description |
|---|
| POST | /api/intel/sweep/launch | Launch sweep as background task, returns 202 |
Target detail page
/intel/targets/<target_id> is the primary workspace for a single target. Three sections render the target’s evidence, most-recent-first:
- Imports —
#imports
- Probe Runs —
#probe-runs
- Sweep Runs —
#sweep-runs
Each section also deep-links individual runs (#import-run-<run_id>, #probe-run-<run_id>, #sweep-run-<run_id>).
Imports section
Lists every import run (module = import) bound to the target. Each row carries:
- an age badge (
12d / 2h / now / —),
- the source label (Garak / PyRIT / SARIF / scored-prompts / BIPIA),
- the finding count,
- the run status.
Rows link to /runs?run_id=<run_id> — the standard Runs detail view for import runs.
Probe Runs section
Lists every probe run (module = ipi-probe) bound to the target. A summary line under the section header describes the latest probe — Latest probe: <age> ago — N probes across C categories, X% compliance, <severity> severity, <status>. Each row shows the finished-at age, probes × categories, overall compliance, severity, and status.
Rows link to /runs?run_id=<probe_run_id>. Bookmarked Run History deep links of that shape redirect (302) here to #probe-run-<probe_run_id>, keeping intelligence surfaces on the Intel target page rather than the Run History view.
Sweep Runs section
Lists every sweep run (module = ipi-sweep) bound to the target. The summary line describes the latest sweep — Latest sweep: <age> ago — T templates × S styles, N=<reps>, <status>. Each row shows the finished-at age, the template × style combo count, the rep count, and status.
Rows link to /runs?run_id=<sweep_run_id> and carry the #sweep-run-<id> anchor for deep-linking. Bookmarked Run History deep links of that shape redirect (302) to the same anchor.
The Generate affordance sits at the bottom of the Sweep Runs section. Its rendering is re-evaluated on every page load — there is no caching. The taxonomy covers five states, grouped by user-visible behavior:
Button renders (you can launch generate)
SelectedTemplate — fresh. Latest sweep is 7 days old or newer, and one template clearly leads the pack. The button reads Generate with <TEMPLATE> and links to /launcher prefilled with the target and template.
SelectedTemplate with stale_warn — a template recommendation is available, but the latest sweep is 8–30 days old. The button renders muted and appends the age to the label (e.g., Generate with CITATION (12d ago)). Click-through still works; the hint is to consider re-running the sweep first.
Button does not render — inline explanation instead
TieRefusal — the top two templates are within 10 percentage points of each other. The section shows a note listing the templates in the tie band and suggests either re-running the sweep with more reps or picking a template explicitly from the launcher.
StaleRefusal — the latest sweep is more than 30 days old. The section shows a note with the sweep’s age and prompts a fresh sweep.
No sweep findings yet
NoFindings — at least one sweep run exists for the target, but none produced usable findings. The section shows a link back to the Sweep card on /intel. When the target has no sweep runs at all, the Sweep Runs section itself shows the empty-state prompt to run a sweep.
The thresholds here (10 percentage-point tie band, 7-day stale-warn, 30-day stale-refuse) match the CLI’s qai ipi generate --target contract — see IPI CLI — Auto-select from sweep findings.
The (Unbound historical intel) target
One synthetic target with name (Unbound historical intel) and metadata {"kind": "synthetic-unbound"} holds historical probe, sweep, and import runs from before target binding was required. It appears on the Intel target list like any other target, and its detail page surfaces the migrated runs in the usual three sections.
No new unbound runs are created post-Phase-5 — every Intel launcher now requires a target. The synthetic target exists purely so historical runs remain reachable from the target-centric workspace. If your project predates target binding, expect to see it in the list with a backlog of runs attached.
Next steps