# On an existing site

> Adding droost to a site that already has code, a team and its own habits: start with a baseline of the old problems, so new runs are judged only on what they add.

A new site has no old code, so every problem a check finds is new. An
existing site is different: run phpcs or phpstan over it and you will usually
get hundreds of problems nobody wrote this week. If droost judged every run on
all of them, the first change that touched an old file would fail, and keep
failing, on work that is not the agent's.

The fix is a **baseline**: a record of the problems the site has today, so a
run is judged only on what it adds. Write it before the first run.

## The order

Install droost the usual way first ([Set up by hand](https://droost.org/docs/setup-by-hand.md) or
[with AI](https://droost.org/docs/setup-with-ai.md)), then:

1. Commit or stash any work in progress.
2. Pick the level.
3. Install the tools the checks use.
4. Measure the old problems.
5. Write the baseline, and commit it.
6. Start your first run.

The order matters. The baseline records only the checks the level turns on,
and a later refresh can only remove problems, not add them (see
[Raising the level later](#raising-the-level-later)). Set the level first.

## 1. Start from a clean tree

droost does not count changes it finds in your working folder when a run
begins as the run's own. Leftover edits make the first run's checks look at
the wrong files. Commit or stash them first.

## 2. Pick the level

From your own terminal:

```bash
droost workflow:effort high
```

`droost workflow:effort high --preview` shows what a level turns on without
writing anything. [Settings](https://droost.org/docs/settings.md#levels) has the table.

## 3. Install the tools

```bash
composer require --dev drupal/core-dev     # phpcs, phpstan, phpunit
npm i -D @playwright/test && npx playwright install chromium
```

If the project already has its own `phpcs.xml(.dist)` or `phpstan.neon`,
droost's checks use it, and the baseline is measured with it too.

## 4. Measure the old problems

```bash
droost workflow:baseline --measure
```

This runs each check the level turns on over the whole site, so on a big
site it takes as long as a code step. It writes nothing, and prints (as JSON)
the level, the **bill** (how many problems each check would record) and
`skipped`: each check it could not measure, and why. A tool that is missing
or crashes is listed there, never recorded as clean.

Read the numbers before you write them down. A check with thousands of
problems may be pointed at the wrong folders (`vendor/`, a contrib module
copied into `modules/custom/`).

## 5. Write the baseline

From your own terminal, between runs (the agent cannot write it, since a
baseline the agent could write is a problem it could hide; and it is refused
while a run is open):

```bash
droost workflow:baseline
git add droost/baseline/
git commit -m "droost: record the baseline"
```

It is written to `droost/baseline/`, one file per check, and committed like
any other code, so the team sees what was accepted.

`droost workflow:baseline --status` shows what is recorded.

## What a run sees now

A check that passes says how much of what it found was already there:

```text
phpcs     passed: 0 new, 312 inherited
```

- Only new problems fail a run.
- For phpcs, eslint and stylelint, a problem belongs to its line's text. A
  line the change edited counts as new, even if its problem is old, so the
  agent fixes what it touches; a line that only moved, or was re-indented,
  stays inherited.
- For prettier, an unformatted file stays inherited until a run touches it.
- phpstan uses its own baseline file, which droost writes and points phpstan
  at.
- The baseline is frozen when each run starts, so it cannot change under a
  run.

What it covers: phpcs, phpstan, eslint, stylelint, prettier, and the coverage
and mutation floors. Tests are not baselined. A failing phpunit or Playwright
test is broken, not old, and fails the run until it is fixed or skipped in the
test itself.

## Paying it off

As the team fixes old problems, record the smaller number:

```bash
droost workflow:baseline --refresh
```

A refresh only ever shrinks the baseline: fixed problems drop out, and if it
finds more than before it refuses and names them.

## Raising the level later

A higher level turns on more checks, or makes one stricter (phpstan's level,
for example), and those find old problems the baseline never recorded. A
refresh refuses to add them unless you say why:

```bash
droost workflow:baseline --refresh --grow --reason="raised to xhigh"
```

The reason is kept in the baseline's record for good.

## Your team, alongside the agent

- **People are not blocked.** The guard holds the agent, not your editor.
  Anyone can still edit and commit as before.
- **The agent edits custom code only inside a run.** With `require_run: hard`
  (what `init` writes), an agent asked for a quick fix outside a run is
  refused. To let it, run `droost workflow:bypass "<why>"` in your terminal,
  and `droost workflow:bypass --off` after; or set `require_run: soft` in
  [Settings](https://droost.org/docs/settings.md).
- **Your own instructions are kept.** `init` adds droost's section to
  `AGENTS.md` and `CLAUDE.md` between marker comments and leaves the rest of
  each file alone.
- **The wiki starts thin.** On day one droost knows your modules and your
  code from the files, but has none of your team's notes. Each run adds what
  it built to `droost/wiki/`; you can add pages of your own there too.

## When the first run still fails on old code

Read the gate's message. If the problems are in files the run did not touch,
it names them. Usually that means the baseline was written at another level,
or before a tool was installed; measure again and refresh. See
[Troubleshooting](https://droost.org/docs/troubleshooting.md).
