# Settings

> droost/droost.yml, the one settings file: the level, who drives and who finishes a run, the gates, and the retries.

Every setting droost has for your project is in one file,
`droost/droost.yml`. `droost init` writes it once and never overwrites it.

It is a file, not site configuration, for three reasons: the agent can read
it even when the site is broken; every agent reads the same file; and a change
to it shows up in code review as a diff. While a run is open, the guard
refuses edits to it, so a change applies to the next run.

## The main settings

```yaml
preset: custom        # the level
mode: agentic         # agentic | interactive
# lead: human-led     # human-led | autonomous (unset: autonomous in agentic mode)
enforcement: soft     # hard | soft | off
require_run: hard     # hard | soft | off
max_gate_retries: 2
```

These are the lines `droost init` writes.

| Setting | What it decides |
|---|---|
| `preset` | the level: how much each run must prove (below) |
| `mode` | `agentic`: the agent moves the run along itself. `interactive`: it stops at each step for you |
| `lead` | who may finish a run: you (`human-led`) or the agent (`autonomous`). Unset, an agentic run is autonomous |
| `enforcement` | how the guard holds a run to its step: `hard` blocks, `soft` warns once, `off` drops the step rules (the walls, `require_run`, the protected files and your commands still hold) |
| `require_run` | whether edits to `modules/custom` and `themes/custom` need a run open: `hard` blocks, `soft` warns, `off` allows |
| `max_gate_retries` | how many times a failing check is retried in place before its step stops (2 means one try plus two retries) |

Setting `lead:` here decides it for runs from now on. To change it for one run
that is already open, run `droost workflow:lead <lead>` (making a run
autonomous needs your own terminal).

## Levels

The level is how strict each run is. Two things never change with it: the
agent always writes a spec, and it always has to look at the code first.

| Level | In plain words |
|---|---|
| `low` | Code style, light static analysis and browser verification. No PHP tests required, no reviewer. For trying droost out. |
| `medium` | A run that changes a class must also change a PHPUnit test. A second agent reviews each change. |
| `high` | Stronger code analysis. The guard blocks out-of-step edits, and a critical review finding holds the run. Every check runs again at the end. **A good default.** |
| `xhigh` | Adds test coverage, mutation testing, and JavaScript and CSS linting. |
| `max` | Everything on, at the strictest settings. Test suites must exist: an empty one fails. |
| `custom` | Your `gates:` list decides everything. What `init` writes. |

A file that names no level is held to `max`.

**What a level decides, and what your file does.** A setting written out in
the file beats the level. The file `init` writes spells out several,
including `enforcement: soft`, phpstan's `level: 6`, `mutation` and `coverage`
off, the seeker and `max_gate_retries`. To let a level decide one of them,
delete its line. `droost workflow:status` lists the ones still overriding it.

**How the checks run differs by level.** At every level the code checks read
only the files the run changed. At `low` and `medium`, each check also runs
just once, in the step that owns it, and the test suites run only the tests the
run changed; a test failure sends the run back to code, up to 2 times at `low`
and 3 at `medium`. From `high` up, and at `custom`, the code checks run again
at test and every check runs again at complete.

Change the level in your own terminal:

```bash
tools/droost/vendor/bin/droost workflow:effort xhigh --preview   # what would change
tools/droost/vendor/bin/droost workflow:effort xhigh
```

A run keeps the level it started with.

## Gates

Each built-in check is listed under `gates:`. The level sets them; what you
write here is applied on top, one gate at a time:

```yaml
gates:
  phpcs:      { standard: "Drupal,DrupalPractice" }
  phpstan:    { level: 6, paths: "web/modules/custom,web/themes/custom" }
  playwright: { on: true, required: true }
  parity:     { on: true, scope: frame }
```

Every gate takes `on`, `mode` (`block` or `report`) and `timeout`.
[Gates](https://droost.org/docs/gates.md) lists them all; your own go here too
([Make it yours](https://droost.org/docs/hooking-in.md)).

phpcs, phpstan and phpunit cannot be switched off here, except at `custom`.
At `low` the level itself turns phpunit off, and the report says "off by preset
low", never "passed".

## Everything else

| Setting | Where |
|---|---|
| `seekers:` | [Gates](https://droost.org/docs/gates.md#the-seeker) |
| `rules:` | [Make it yours](https://droost.org/docs/hooking-in.md#house-rules) |
| `hooks:`, `walls:`, `operator_only:`, `panel:` | [Hooks and walls](https://droost.org/docs/hooks-and-walls.md) |
| `work_item:` | [Tickets](https://droost.org/docs/tickets.md) |
| `baseline:` | [Gates](https://droost.org/docs/gates.md#old-code-the-baseline) |

Near-miss spellings of known settings are rejected. Unknown top-level keys
are allowed for project extensions; check `workflow:status` to see the
resolved configuration.
