# Contributing

This is the canonical development workflow for `rosotacom`.

For the diagnosis-first quality workflow and owner-facing entrypoints, see
[docs/quality-model.md](docs/quality-model.md) and
[docs/owner-runbook.md](docs/owner-runbook.md).

## Development Setup

Prerequisites:

- Python 3.10 through 3.14 when mirroring CI.
- Docker for runtime and E2E checks.
- `just` for local workflow commands.
- GitHub CLI `gh` for issue and PR workflows.

Set up the repository from the root:

```bash
just setup
```

This creates `.venv`, installs `.[dev]`, and installs pre-commit hooks.

## Local Checks

Run individual checks from the repository root:

```bash
just lint-workflows
just lint-build
just lint
just typecheck
just test-unit
just test-contract
just test-nondocker-cov
just docs
just package
just test-e2e-smoke
```

Before opening or updating a ready PR, run:

```bash
just check
just test-e2e-smoke
```

`just check` runs linting, type checking, host tests under coverage, docs checks,
and package validation. `just test-e2e-smoke` runs the required Docker-backed
single-machine smoke matrix separately so failures are easier to inspect.

## Branch And Merge Policy

Do not push directly to a protected branch.

All changes must go through a pull request. Repositories using this shared
codebase may use a development branch before the `main` release line. Start each
change from the repository's current default branch:

```bash
git fetch --prune
git remote set-head origin --auto
git switch -c <type>/<short-topic> origin/HEAD
```

Keep the change small and coherent. Update tests, README, docs, examples, and
packaging metadata when CLI, config, package, Docker, or public runtime behavior
changes.

When implementing an RFC, first turn its build plan into actionable checkboxes.
Update those checkboxes, design decisions, and reality checks during the work,
not afterward. The RFC should always describe the current implementation state
and leave enough self-contained context for another contributor to resume.

Every RFC also carries a **Validation checklist** beside its implementation
checklist: one entry per capability it introduces, naming the test, example, or CI
lane that proves it — or, where automation is genuinely impossible, a referenced
manual check. Prefer automated verification (unit/contract test > an example run in
CI smoke > a scripted check) and treat manual checks as the explicit fallback.
Check a validation item only once that verification actually exists and runs, and
add it in the same change as the behaviour it covers. See
[docs/rfcs/README.md](docs/rfcs/README.md) for the required RFC sections.

Soft quality passes start with repository diagnosis and then create only the
focused issues that diagnosis names. See [docs/quality-model.md](docs/quality-model.md)
for the task hierarchy and shared task contract.

Moving validated development work to `main` is a deliberate maintainer action.
It may require an external OTA gate supplied by the repository operator; it is
not triggered by an arbitrary commit in this repository.

## CI Policy

The required merge gate for protected development and release branches is:

```text
ci-success
```

Draft PRs run lightweight checks. Ready PRs, pushes to `main` or `develop`, and
merge queue entries run the full gate: Python 3.10 through 3.14 non-Docker
checks, coverage, package validation, and Docker smoke.

Codecov uses the uploaded `nondocker` report. Docker E2E remains behavioral
validation and is not collected for coverage.

See [docs/ci.md](docs/ci.md) for details and
[docs/github-repository-settings.md](docs/github-repository-settings.md) for
repository settings that live outside git.

## Release Workflow

Two channels, described in full in [docs/release.md](docs/release.md).

**Development channel.** Every commit that lands on the development branch with
green CI is published automatically as `X.Y.devN`. There is nothing to do and
nothing to decide: merging *is* releasing on this channel. Consume such a
version with an exact pin, which is how a downstream repository tracks work in
progress without reaching past the package boundary:

```bash
pipx install "rosotacom-dev==2.4.dev3"
```

**Stable release.** Built from tags in the form `vX.Y.Z`. Release PRs must
include `docs/release-notes/vX.Y.Z.md`, copied from
[docs/release-notes/TEMPLATE.md](docs/release-notes/TEMPLATE.md) — the tagged
commit has to contain its own notes, so the notes land in the PR, not after it.

After the release PR has merged, verify the exact commit and then:

```bash
git switch develop
git fetch --prune
git pull --ff-only
git tag -a vX.Y.Z -m "rosotacom vX.Y.Z"
git push origin vX.Y.Z
```

Tag pushes validate, publish through the repository's configured Trusted
Publisher, and create a GitHub Release. Before any downstream repository sync,
maintainers must review the resulting release workflow, deployment, artifacts,
and release notes. Downstream synchronization is never implied by creating the
tag. Manual release-workflow dispatch validates and builds only; it does not
publish.
