# Decision Tracing

- Canonical URL: https://docs.fairvisor.com/docs/reference/decision-tracing/
- Section: docs
- Last updated: n/a
> How to trace a 429 from response headers back to policy and limiter logic.


Use this flow when debugging unexpected rejects.

## Step 1: Capture reject headers

```bash
curl -i -X POST http://localhost:8080/v1/decision \
  -H 'X-Original-Method: POST' \
  -H 'X-Original-URI: /v1/chat/completions'
```

Collect:

- `X-Fairvisor-Reason`
- `Retry-After`
- `RateLimit-*`

If you need policy/rule attribution, enable a debug session and inspect:

- `X-Fairvisor-Debug-Policy`
- `X-Fairvisor-Debug-Rule`

## Step 2: Map reason -> limiter class

- `token_bucket_exceeded` -> `token_bucket`
- `budget_exceeded` -> `cost_based`
- `tpm_exceeded` / `tpd_exceeded` -> `token_bucket_llm`
- `kill_switch` -> kill switch pre-check
- `loop_detected` / `circuit_breaker_open` -> advanced policy blocks

## Step 3: Verify request context

In `decision_service` mode ensure gateway forwarded:

- `X-Original-Method`
- `X-Original-URI`
- identity headers/JWT used in descriptors

## Step 4: Check descriptor availability

If keys are missing, inspect:

```promql
rate(fairvisor_descriptor_missing_total[5m])
```

## Step 5: Confirm policy/rule intent

- Review selector match and method filters
- Validate rule `limit_keys`, algorithm, and config
- Validate fallback behavior and shadow mode

## Related

- [Rejection Reasons](/docs/reference/reasons/)
- [Troubleshooting](/docs/reference/troubleshooting/)
- [Policy Format](/docs/policy/bundle/)

