# Contributing — mgf-fedres

`mgf-fedres` is a Magogi Foundation sibling and **inherits the cross-project
engineering standards** from
[`mgf-common`](https://codeberg.org/magogi-admin/mgf-common).

## First read

1. [FEDERATION.md](FEDERATION.md) — the contract.
2. [SCOPE.md](SCOPE.md) — what belongs here (the headless spine only; it MUST stay
   web-framework-free).
3. [docs/planning/PLAN.md](docs/planning/PLAN.md) — the approved end-to-end design.

## Process

1. **Bug / feature:** file in [FEEDBACK.md](FEEDBACK.md).
2. **PR:** branch from main; run the gates locally:
   ```sh
   uv run --extra dev ruff check . && uv run --extra dev ruff format --check .
   uv run --extra dev mypy
   uv run --extra dev pytest --cov --cov-report=term-missing
   mgf-fed app-doctor --standards
   ```
3. **Schema / wire changes** carry extra discipline — the schemas are the single
   wire/state authority:
   - keep the document and live-event grammars **symmetric** and self-consistent;
   - a **breaking** wire/state change MUST bump `schema_version` / `v` (the reader
     fails closed on an unknown version — that is the contract, not a regression);
   - keep the Python enums in lock-step with `_common.schema.json` (the test
     `test_sync_states_match_schema` pins this);
   - every shipped example under `examples/` MUST still validate, and a
     hand-corrupted payload MUST still fail closed.
4. **Keep it headless** — no imports of `fastapi`/`starlette`/`jinja2`/etc. The
   webs and the warden depend on this core staying framework-free.
5. **CHANGELOG.md:** add an `[Unreleased]` entry.
6. **CI is generated:** never hand-edit `.woodpecker.yml`; regenerate with
   `mgf-fed scaffold mgf-fedres` (WF-13).
7. **Reviewer:** the federation owner (mgf-common maintainer).

## Release flow

Bump `pyproject.toml::version` + `mgf.fedres.__version__` → build → test →
`twine check` → commit → tag `vX.Y.Z` → push tag (CI publishes to devpi) → regen
the registry (REL-13). As the spine, publish before `mgf-fed-web` / `mgf-test-web`
re-pin.
