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

# ScriptedApprovalProvider

> A human replaced by a fixed script: for tests and `ctrlrun demo` (SPEC-v0.1 §4.3).

`ctrlrun.ScriptedApprovalProvider` — class, defined at `src/ctrlrun/approval.py:425`

```python theme={null}
class ScriptedApprovalProvider()
    def __init__(store: ApprovalStore, script: Iterable[str | ScriptedOutcome], approver: str, clock: Callable[[], datetime])
```

A human replaced by a fixed script: for tests and `ctrlrun demo` (SPEC-v0.1 §4.3).

Each `wait()` poll takes the next step. `PENDING` means "no answer yet", so a script can
make `wait=True` genuinely block. The script is one sequence shared by every request, in
poll order. An exhausted script raises `ApprovalTimeout`: a scripted approver never
grants by accident, and a test can never hang waiting for a step that will not come.

The script does not outrank the clock. A step that lands after the request has expired
raises `ApprovalTimeout` and is not applied, so the double cannot grant something the
real provider would have refused (SPEC-v0.1 §4.3).

## Next

* [Python API index](/reference/api/index).
* [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Python API](/reference/api/index.md)
- [ApprovalProvider](/reference/api/ApprovalProvider.md)
- [InterruptApprovalProvider](/reference/api/InterruptApprovalProvider.md)
- [WebhookApprovalProvider](/reference/api/WebhookApprovalProvider.md)
- [LocalApprovalProvider](/reference/api/LocalApprovalProvider.md)
