# Contributing to yothere

yothere is a shipped product that other systems (bob, SIDES) depend on. Two people
build it, and neither should be able to break `main` alone. This is our working
agreement.

## Golden rule

**Never commit to `main` directly.** Every change flows:

```
branch  →  pull request  →  CI green  →  merge
```

`main` is protected on GitHub: no direct pushes, and nothing merges until the
required checks (`test (3.11)`, `test (3.12)`, `postgres`) are green and every
conversation is resolved.

**Green CI is the gate, not the other founder.** Either of us can merge our own
PR once it goes green. We do not wait on each other. This is deliberate: a review
queue between two people in different timezones cost us more in shipping speed
than it ever caught in bugs, so we moved the gate into CI, where it runs in two
minutes and never sleeps.

## Asking for a review

Review is now opt-in, and it is on the **author** to ask for it. Ask when the
change is one you would want a second pair of eyes on:

- `src/yothere/` core (runner, watchdog, fleet, brain, auth, registry)
- the brain protocol (`docs/brain-protocol-v1.md` and the wire code implementing it)
- `deploy/` (Dockerfile, entrypoint, fly config)
- DB schema, migrations, or the auth store
- `.github/workflows/` (CI/release)
- `pyproject.toml`, dependencies, or anything that cuts a release/tag
- anything that breaks the Brain Protocol or a consumer (bob, SIDES)

To ask, request the review on the PR and say so in the description. Then wait for
it. Requesting a review and merging past it defeats the point of asking.

Everything else (docs, comments, CHANGELOG, tests, copy) just merges on green.

## Before you merge (author)

- Tests pass locally:
  ```bash
  PYTHONPATH=src python tests/relay_test.py
  # plus the feature suites you touched, e.g.
  PYTHONPATH=src python tests/test_registry.py
  ```
- CHANGELOG updated if the change is notable.
- PR is scoped small. Split unrelated changes into separate PRs.
- Fill in the PR template (it loads automatically).
- If the change touches anything on the list above and you did not ask for a
  review, be sure you can defend that call.

## Merging

Squash-merge, and the branch is auto-deleted:

```bash
gh pr merge <n> --repo phios-ai/yothere --squash --delete-branch
```

`main` must be up to date first (GitHub enforces this). No `--admin` flag is
needed any more; if you find yourself reaching for one, the checks are telling
you something.

## Emergency escape hatch

Admins can bypass the gate (`enforce_admins` is off). Now that the gate is CI
rather than a human, bypassing it means **merging code with red or missing
checks**, which is a much sharper thing to do than skipping a review used to be.
It exists only for a genuine emergency: prod is down, or a live security issue.

If you bypass, you must:

1. Post the diff to the other person immediately, and
2. Open a follow-up PR the same day that gets the checks green again.

Never bypass because a check is flaky or slow. Fix the check.

## Branch naming

`feat/…`, `fix/…`, `chore/…`, `docs/…`.
