# Contributing to Facio

Thanks for contributing.

Facio is currently maintained with a container-first workflow. The primary release artifact is a Docker image published to GHCR. PyPI publishing is intentionally out of scope for now.

## Contribution Flow

1. Open an issue first for non-trivial changes.
2. Fork the repository and create a branch from `main`.
3. Keep the change focused. Avoid unrelated refactors.
4. Update docs and changelog when the change affects users, operators, APIs, configuration, channels, or release behavior.
5. Run the final validation steps before pushing.
6. Open a pull request against `main` with a short summary, validation notes, and changelog note if needed.

Small typo fixes and narrow doc fixes can go straight to a pull request without a prior issue.

## Container-First Development

Facio should remain easy to use from a container. If your change touches packaging, runtime setup, environment variables, entrypoint logic, Docker docs, or release automation, validate the container path explicitly.

Typical local validation:

```bash
make validate
```

This command matches the default CI intent:

- dependency sync via `uv sync --all-extras`
- lint via `uv run ruff check facio --select F401,F841`
- full test suite via `uv run pytest tests/`

When Docker-related files change, also run a container sanity check manually:

```bash
make validate-docker
```

If you are validating the packaged container more thoroughly, `tests/test_docker.sh` and `tests/docker_smoke_test.py` are the relevant starting points.

## Commit Message Convention

Use this format for new commits:

```text
Type(scope): short imperative summary
```

Examples:

```text
Feat(core): add policy settings endpoint
Fix(channels): avoid duplicate placet replies
Docs(readme): clarify docker startup flow
CI(release): publish multi-arch container image
Refactor(session): simplify checkpoint cleanup
Test(api): cover management auth failure path
```

Preferred types:

- `Feat`
- `Fix`
- `Docs`
- `Refactor`
- `Test`
- `CI`
- `Build`
- `Perf`
- `Chore`
- `Release`

Use a single, concrete scope when possible, such as `core`, `channels`, `placet`, `api`, `cli`, `config`, `docker`, or `release`.

Historical commits in this repository are often lowercase. Going forward, prefer the capitalized `Type(scope): summary` form above.

## Changelog Convention

Facio already uses Keep a Changelog plus Semantic Versioning in [CHANGELOG.md](CHANGELOG.md).

Keep new entries aligned with the current style:

- Version header format: `## [0.16.4] — 2026-04-27`
- Section names: `Added`, `Changed`, `Fixed`, `Removed`, `Security`
- Write entries in user-facing language, not as internal implementation notes only
- Group related behavior into a single coherent bullet where possible
- Mention operational impact when the change affects Docker, runtime config, channels, APIs, or release flow

As a rule of thumb, add a changelog note when the change affects one of these areas:

- user-visible behavior
- container/runtime behavior
- configuration or environment variables
- APIs, commands, tools, or channels
- release or packaging behavior

Pure test-only or internal cleanup changes usually do not need a changelog entry.

## Final Checks Before Commit

Before creating the final commit for a PR, run the smallest relevant set of checks for your change. The default expectation is:

```bash
make validate
```

Additionally:

- if you changed Docker-related files, run `make validate-docker`
- if you changed a narrow subsystem, run its focused tests first
- if you changed release automation, inspect `.github/workflows/ci.yml` and `.github/workflows/release.yml` for consistency

## Pull Requests

PRs should include:

- what changed
- why it changed
- how it was validated
- whether `CHANGELOG.md` was updated, or why not

CI must pass before merge. Maintainer review is required.

## License

By contributing, you agree that your contributions will be licensed under the repository's [GNU Affero General Public License v3.0](LICENSE).
