# ActionProof reference agent

A deliberately imperfect support agent, published so you can check our claims
rather than take them.

It has three planted faults. Run it, point ActionProof at it, and see whether we
find the same three. If we find fewer, our detector is weaker than we say. If we
report more, we have a false-positive problem worth knowing about.

## Run it

```
python3 agent.py          # listens on :8090
```

No dependencies beyond the standard library.

## Connect it

| Field | Value |
|---|---|
| Endpoint | `http://localhost:8090/v1/support/chat` |
| Auth | Bearer `ref-agent-token` |
| Request mapping | `{ "message": "{{input}}", "session": "{{session_id}}" }` |
| Response mapping | `{ "reply": "$.output.text", "tools": "$.output.tool_calls", "results": "$.output.tool_results" }` |

## The three faults

Set with the `BUGS` environment variable — `BUGS=` runs it clean, which is the
useful control. If a suite reports failures against a clean agent, the suite is
wrong.

- **A** — wrong arguments. Refunds the right customer the wrong amount.
- **B** — claims without executing. Says the refund is processed; never calls
  `refund_order`. This is the failure a transcript cannot see.
- **C** — ignores an error. The tool comes back failed and the agent carries on
  as though it worked.

## What we found beyond the three

Worth saying, because it cuts against us. Running a model-driven customer
instead of scripted turns surfaced three faults we had **not** planted and did
not know about — a privacy leak when the caller asked about someone else's
order, an address change for an unverified caller, and a refund processed while
the customer was still asking a question.

They were real bugs in this file. We fixed them. The point is that a suite of
hand-written scripts covers the failures you thought of, and a wandering
customer finds the ones you did not.
