# hotato webhook worker ({{STACK_TITLE}})

A small, self-hostable {{TARGET}} worker that turns your {{STACK_TITLE}} calls
into a passive turn-taking regression monitor. It receives the call-ended
webhook, fetches the dual-channel recording **read-only**, and scans it for
**candidate** turn-taking moments (talk-over onsets and long response gaps). It
never mutates your {{STACK_TITLE}} config and never labels intent.

Generated by `{{GENERATED_BY}}` on hotato {{VERSION}}.

## What it does

```
{{STACK_TITLE}} webhook  ->  verify secret  ->  hotato ingest (read-only fetch + scan)
                                                     |
                                       reports/<call>.json + <call>.html
                                                     |
                                     optional: Slack summary / GitHub notice
```

`hotato ingest` is **discovery, not a verdict**: it surfaces candidate moments,
never a pass/fail and never an intent claim. You review the report and promote a
real one to a permanent regression test with `hotato fixture promote` (see the
[hotato docs](https://hotato.dev)). The worker never labels for you.

## The four invariants (held in `app.py`, asserted in `tests/test_webhook_contract.py`)

1. It never calls a {{STACK_TITLE}} config-mutation endpoint (all vendor I/O is
   delegated to `hotato ingest`; the worker holds no vendor API host).
2. It never labels intent or emits a verdict -- discovery only.
3. It verifies the webhook secret **before** any parse, fetch, or scan.
4. The recording fetch is read-only.

## Run it

```bash
cp .env.example .env          # fill in your {{STACK_TITLE}} secrets
pip install -r requirements.txt
uvicorn app:app --reload      # POST /webhook  ;  GET /health
pytest -q tests/test_webhook_contract.py   # the invariants above
```

Point your {{STACK_TITLE}} call-ended webhook at `POST /webhook`. The worker
verifies the `{{SECRET_HEADER}}` secret (set `{{SECRET_ENV}}`), then hands the
payload to `hotato ingest`.

## Configure

Runtime settings come from environment variables (`.env.example`); `hotato.yaml`
is the human-readable contract. Slack and GitHub notifications are **off** by
default; the GitHub path opens **no** issue unless you explicitly set
`HOTATO_GITHUB_CREATE_ISSUES=1` with a repo and token.

## Deploy

`Dockerfile` builds a container that serves `app:app` on `$PORT`.
`.github/workflows/deploy.yml` runs the contract test, builds the image, and
leaves a labeled slot for your platform's deploy step.
