---
name: anomaly-detect
description: Surface unusual transactions for user review. Reads a configurable rules.yaml; rules fire on commit and on a daily cron pass. Read-only — flags only, never edits transactions.
allowed-tools: query_finance
title: Anomaly Detect
category: finance
status: active
metadata:
  triggers:
  - anomalies
  - unusual transactions
  - spending spike
  - weird transactions
  priority: 4
  model_tier: fast
  language:
    output_policy: source
---
## What this skill is

The accountant's daily watchdog. Walks recent verified transactions and flags ones that look unusual against a YAML-configured rule set. Does NOT modify any transactions — anomaly detection is suggest-only, the user decides whether each is genuine.

## When to use

- Daily heartbeat sweep after the EOD report runs.
- User-initiated query: "Anything weird in my spending this week?"
- Post-approve hook: when the bookkeeper commits a draft, run anomaly check before activity event fires.

## Flow

1. Read window of verified transactions (default: last 30 days).
2. Apply each rule from `config/rules.yaml` — each rule is a deterministic predicate that returns true/false per transaction.
3. For every flagged transaction, accumulate `(txn_id, rule_name, reason_template, severity)`.
4. Group by severity. High-severity flags surface as proactive outreach (when enabled); medium-severity flags accumulate in the daily report; low-severity flags are silent until the user asks.
5. Return a structured list with the user's decision affordances.

## Rules
- READ-ONLY. NEVER edit transactions, NEVER mark anything as fraud, NEVER auto-archive a flagged row. Surface for user review only.
- NEVER fabricate a rule. Every flag must trace to a rule_name in `config/rules.yaml`.
- NEVER fire the same flag for the same txn_id more than once per heartbeat cycle (idempotent on (txn_id, rule_name) within the window).
- NEVER apply rules to draft / rejected / archived transactions — only verified.

## Output format

```
## Anomalies — last {window} days

### High severity
- {txn_id}: {merchant}, {amount} {currency}, {date}
  Rule: {rule_name}
  Reason: {reason}

(repeat per flag, grouped by severity)
```

End with a 1-line action prompt: "{N} flags total — review at /finance?filter=flagged"

## Examples

User: "Anything weird this month?"

Output (with rules `large_amount` and `late_night_spend` firing):

> ## Anomalies — last 30 days
>
> ### High severity
> - t_abc123: Whole Foods, $1240.50 USD, 2026-04-12
>   Rule: large_amount
>   Reason: total > 5x merchant median ($240)
>
> ### Medium severity
> - t_xyz789: Best Buy, $89.00 USD, 2026-04-15 02:13 local
>   Rule: late_night_spend
>   Reason: transaction time falls in 00:00–05:00
>
> 2 flags total — review at /finance?filter=flagged