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

# AI Movement Narratives

> One-click 1-2 sentence AI summaries explaining how a prop's line has moved, grounded in actual snapshot data — not betting advice or speculation.

When you expand a prop on the [dashboard](/features/dashboard), you'll see an **"Explain this movement"** button. Click it, and an AI returns a 1-2 sentence factual summary of how that line has moved — grounded entirely in the data we send.

Example output:

> *The line for Donovan Clingan's rebounds has moved up significantly, opening at 6.5 on theScore Bet and now showing a consensus median of 8.5 across seven books. This upward movement is evident across multiple books, with DraftKings, Fliff, and theScore Bet all showing increases from 6.5 or 7.5 to 8.5.*

## What's behind the button

The model receives a structured **fact sheet** for the prop:

* The opening line (book + timestamp)
* The current consensus across all books (median + book count)
* The full movement timeline (last 12 snapshots)
* Any active sharp signals (sync, steam) for the prop

It does **not** receive: player season stats, news headlines, injury reports, betting advice frameworks, or anything else that could be invented. By design.

## Anti-hallucination

The system prompt locks the model to four hard rules:

1. **Use only the data provided.** No invented stats, injuries, news, or external context.
2. **If the data is sparse, say so.** Don't speculate.
3. **No betting advice.** No "bet the over" or "fade this." Pure factual summary.
4. **Maximum 2 sentences.** Forces concision; reduces drift.

The output panel itself reminds you: *"Grounded in actual line movement data only — not betting advice."*

## Cost & caching

<CardGroup cols={2}>
  <Card title="Cached per snapshot" icon="database">
    Narratives are cached by `(player, game, prop, latest_snapshot_id)`. The same prop with the same most-recent snapshot serves from cache — no token spend on repeat clicks.

    A new snapshot invalidates the cache, so the next click after movement gets a fresh narrative.
  </Card>

  <Card title="Daily token budget" icon="gauge">
    A daily token cap prevents runaway spend. If the budget is hit, the button returns *"AI explanations are temporarily unavailable — daily budget reached. Try again tomorrow."*

    Defaults to 100k tokens/day (\~\$1-2 on Gemini Flash).
  </Card>
</CardGroup>

## Provider

The default is **Gemini 2.5 Flash** (cost-efficient, factual). The codebase ships with a swappable adapter, so we can switch to Anthropic Claude or another provider via a single env var without code changes.

If you'd rather self-host or use your own provider, the architecture supports that — but the default is what you'll see.

## What this isn't

* **Not a sharps prediction.** The narrative describes what happened, not what will happen.
* **Not a betting recommendation.** The model is explicitly instructed never to suggest a side.
* **Not real-time.** The narrative reflects the data as of the latest 30-minute snapshot, not sub-second odds.

## Coming soon

<Card title="Quality eval harness" icon="microscope">
  <span className="text-xs text-muted-foreground">Tracked as follow-up</span>

  Automated testing of narrative quality against historical movements (looking for hallucinations, factual drift, voice consistency). For now, output is monitored manually and the prompt-level safeguards are the primary defense.
</Card>
