> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# 03 — Verify

> **Source**: `callytics-infrastructure/lambda/ai-analysis-processor/src/core/stages/verify.ts:39-52` (verified 2026-06-01)
> **Stage in pipeline**: Stage 2.5 (boundary check, runs only when Stage 2's `subcategory` is in the known-confusable set; the caller `pipeline.ts:resolveVerifyDecision` decides whether to adopt the verify call — verify is treated as authoritative only when it disagrees with classify AND clears a confidence bar) — see [unified-pipeline-final.md](/product-design/v2/unified-pipeline/unified-pipeline-final.md)
> **Input**: Candidate subcategories (predicted + confusion-pair siblings), contrastive boundary examples for each pair, and the actual transcript (first 3000 chars). User-message builder lives in the same file (`buildVerifyUserMessage`).
> **Output**: JSON `{subcategory, confidence, reasoning}` where `subcategory` MUST be one of the provided candidates.
> **Writes to schema**: When adopted, overrides `calls.primarySubcategory` (and downstream `primaryCategory` if the new subcategory implies a different parent category) — see [../../calls-feature/calls-schema.md](/product-design/v2/calls-feature/calls-schema.md)

## Full system prompt

```
You are an independent classification specialist for a gym call analytics system.

Your job: Given a call transcript and a set of candidate subcategories, determine which subcategory BEST matches the transcript.

You will receive:
1. The candidate subcategories to choose from
2. Contrastive examples showing the boundary between them
3. The actual transcript

RULES:
- Reason from the transcript EVIDENCE, not from the proposed label
- Look for the KEY DISTINGUISHING SIGNALS mentioned in the examples
- Output the subcategory YOU believe is correct — ignore what the classifier said
- Your answer must be one of the provided candidates
```

## Output schema

Defined as a Zod schema in `verify.ts:19-35`:

```json
{
  "subcategory": "<one of the provided candidate subcategories>",
  "confidence": 0.0,
  "reasoning": "<≤200 words; key transcript evidence and specific phrases/signals>"
}
```

Field semantics (from Zod `.describe()`):

- `subcategory`: "The subcategory YOU believe is correct based on transcript evidence. Must be one of the candidates provided."
- `confidence`: "How confident you are in your classification. >0.8 = strong signal."
- `reasoning`: "Key transcript evidence that led to your conclusion. Reference specific phrases or signals. Keep under 200 words."

## User-message shape (from `buildVerifyUserMessage`)

```
CANDIDATE SUBCATEGORIES: <predicted>, <confusion_pair_1>, <confusion_pair_2>, ...

--- BOUNDARY EXAMPLES ---
[<label>] "<transcript_excerpt>"
  → Why: <reasoning>

[<label>] "<transcript_excerpt>"
  → Why: <reasoning>

--- TRANSCRIPT ---
<transcript, truncated to 3000 chars>

Based on the transcript evidence, which candidate subcategory is correct?
```

Confusion pairs and contrastive examples are sourced from `confusion-pairs.ts` and `contrastive-examples.ts` respectively.

## Cross-references

- Calls schema: [../../calls-feature/calls-schema.md](/product-design/v2/calls-feature/calls-schema.md)
- Stage 2 (Classify) prompt: [02-classify.md](/product-design/v2/unified-pipeline/prompts/02-classify.md)
- Pipeline overview: [../unified-pipeline-final.md](/product-design/v2/unified-pipeline/unified-pipeline-final.md)
