# mgf-common v0.35 → v0.41.2 — Multi-minor cutover guide (PAPER-82)

> **Audience:** consumers crossing more than one minor between v0.34 and v0.41.2. This is the consolidated migration story for the **seven-minor gap** previously covered by individual per-minor cutover docs that were never written (PAPER-82). For per-release detail beyond what's here, the `CHANGELOG.md` entries for each minor are the authoritative record.
> **Audience NOT covered:** single-minor jumps (e.g., v0.40 → v0.41). The corresponding per-minor stubs (`v0.35.0.md` … `v0.41.2.md`) cross-reference this guide; if you're crossing only one minor, the CHANGELOG entry is usually enough.

---

## Why a span-cutover guide

Per `STARTHERE.md` (line 242): *"the cutover guide is the canonical migration story; `migrate` handles the mechanical parts."* The federation's cutover-doc pattern is per-minor — one `docs/cutover/v0.XX.0.md` per release. But the v0.35 → v0.41.2 window grew faster than the docs cadence:

- v0.34 ↔ v0.35: cutover doc skipped (no breaking changes thought to require one)
- v0.35 → v0.36 → v0.37 → v0.38 → v0.39 → v0.40 → v0.41 → v0.41.1 → v0.41.2: nine releases, zero cutover docs.

PAPER-82 (filed by iosRecovery 2026-05-26) is the formal callout: *"consumers crossing 3+ minor versions get no migration guide."* This file is the catch-up: a single span-cutover that lets a consumer on 0.34 read ONE doc and know what changed by 0.41.2.

---

## Big picture: what shipped across the span

The federation went through three reshaping waves between 0.35 and 0.41:

| Wave | Releases | Theme |
|---|---|---|
| **Wave 1 — Feature surface expansion** | v0.35 / v0.36 / v0.37 | Eight new subpackages land at `experimental` tier: `flags`, `schedule`, `plugins`, `doctor`, `health`, `idempotency`, `rate_limit`, `cache`. Federation rule taxonomy expands (NM-01..NM-04 naming standard, AGENTS, TIME, PERFORMANCE, OBSERVABILITY standards). |
| **Wave 2 — Stability promotions** | v0.38 / v0.39 | 50 names promoted from `experimental` to `stable (v1.0.0)` (`v1_0_stability_audit.md`'s 50-name set). Soft-deprecations begin (v0.1-pattern shims for v0.32-era APIs emit `MgfDeprecationWarning`). |
| **Wave 3 — Cornerstone reshape** | v0.40 / v0.41 / v0.41.1 / v0.41.2 | Federation test supervisor lands as in-tree at 0.40 then extracts to published sibling `mgf-test-supervisor` 0.1.x at 0.41. Pre-v1.0 deletions: 4 observability shims, 12 N818 exception aliases, vault dict-shape config, `build_parser` alias. PUBLIC_API.md reshape: 5 sibling-extracted subpackages converted to redirect stubs. PAPER-84 cross-sibling pin consistency check lands at 0.41.2 (cohort-safety). |

---

## What's broken (consumer-facing)

### From v0.40 → v0.41 (the biggest cliff)

These are the **deletions** that catch consumers crossing into 0.41. Pre-v1.0 break-freely discipline (`feedback_pre_v1_break_freely`) authorised them.

| Was | Now | Migration |
|---|---|---|
| `mgf.common.observability.setup_logging(...)` | `mgf.common.bootstrap(setup_logging=True, ...)` | Switch to `bootstrap()` — the orchestrator was always the canonical entry. |
| `mgf.common.observability.setup_otel(...)` | `mgf.common.bootstrap(...)` (wires OTel transactionally) | Same — use `bootstrap()`. |
| `mgf.common.observability.install_excepthook()` | `mgf.common.bootstrap(...)` (wires excepthook transactionally) | Same. |
| `mgf.common.observability.install_threading_excepthook()` | `mgf.common.bootstrap(...)` | Same. |
| 12 N818 pre-suffix exception aliases (`AppValidationException`, `UnauthorizedException`, etc.) | Use the `*Error` canonical names | Mechanical find/replace. |
| `Vault*(config={"key": "value"})` dict-shape config | `Vault*(config=EnvVaultConfig(key="value"))` typed model | Read `mgf.common.vault`'s `*Config` model docs. |
| `mgf.common.cli.build_parser(...)` | `mgf.common.cli.build_cli(...)` | Single rename. |

### From v0.39 → v0.40 (test infra reshape)

| Concern | What happened | What you do |
|---|---|---|
| Local supervisor at `scripts/_mtest/` | Project-embedded supervisor (TS-22..TS-27 binding) | Adopt the test supervisor per the standards rules; see `mgf-fed standards testing` |
| `pytest` invocations directly | Federation supervisor: `mgf-fed test` | Either invocation still works; supervisor adds tier-based selection, JSONL outcomes, per-failure detail bundles |

### From v0.40 → v0.41 (supervisor extraction)

| Concern | What happened | What you do |
|---|---|---|
| `scripts/_mtest/` in your project | Extracted to published sibling `mgf-test-supervisor` v0.1.x | Drop the in-tree copy; add `mgf-test-supervisor>=0.1.3,<0.2` to dev extras (or run `mgf-fed catch-up --apply` to insert automatically) |
| `mgf-fed test --self-check` | Same command still works (delegates to the published library) | Continue to use it; behavior unchanged from consumer perspective |

### From v0.41.0 → v0.41.1 / v0.41.2 (patch releases)

These don't break anything for consumers. Pure improvements:

- **v0.41.1** — mgf-common's dev dep on `mgf-test-supervisor` switched from `git+ssh://` to plain PyPI form (made PyPI publish possible for mgf-common itself).
- **v0.41.2** — PAPER-84 cross-sibling pin consistency check. `catch-up --apply` now refuses to bump mgf-common's pin into a state mutually exclusive with another federation sibling's pin. **Net effect for consumers:** if you've previously seen `catch-up` produce an unresolvable `uv sync`, it can't anymore.

---

## Quickest path — catch-up the project, walk the pin

For consumers on `mgf-common>=0.34,<0.35` or earlier, the fastest path:

1. **Bump the pin window** to include 0.41.x in `pyproject.toml`:

   ```toml
   "mgf-common>=0.40,<0.42",
   ```

   The 2-minor bridge window is appropriate during the cohort-walk transition.

2. **Run `uv sync`.** If it fails with a cross-sibling conflict, catch-up's PAPER-84 check will tell you which sibling pin needs walking next; coordinate with the sibling's maintainer or wait for the next sibling release.

3. **Run `mgf-fed catch-up --apply`.** This is the federation's mechanical migration tool. As of 0.41.2 it handles:
   - Stale `[tool.uv.sources]` paths (PAPER-83)
   - Missing federation marker registration (PAPER-66)
   - Missing federation test supervisor wiring (PAPER-73, including the `pytest-timeout` plugin dep PAPER-77 warned about)
   - CLAUDE.md auto-block refresh + pin-literal drift audit (PAPER-72)
   - Federation contract artifacts

4. **Search your project for any of the 7 deletions** (the `Migration` column above). For each match, apply the canonical replacement. The `mgf-fed migrate` codemod handles the N818 alias renames + some patterns; `--dry-run` shows what would change.

5. **Run your test suite.** Anything that still calls a deleted name now fails at collection time (clear traceback).

6. **Run `mgf-fed test -- --self-check`.** Confirms the test supervisor is wired correctly (TS-23 compliance). If it FAILs, the catch-up output will name which piece is missing.

---

## What you do NOT need to migrate

These items LOOK like breaking changes but don't actually require consumer action:

- **5 subpackages "moved" from `mgf.common.*` to siblings** (`mgf.common.fastapi`, `.django`, `.db`, `.http`, `.alembic`) — already moved at v0.28-v0.31. PUBLIC_API.md was just stale until v0.41. If your project still depended on these, you already migrated to the sibling libraries (`mgf-fastapi`, `mgf-django`, `mgf-sqlalchemy`, `mgf-http`, `mgf-alembic`) at the earlier version.

- **`mgf.common.testing` schema types** — these are stable since v0.40 and unchanged in 0.41. If you parse `run.jsonl` files, your code stays the same.

- **The `bootstrap()` orchestrator** — its API is stable across the entire span (the deletions are the OPTIONAL one-step-down helpers that wrapped it).

- **CLI subcommands** — `mgf-fed standards`, `mgf-fed app-doctor`, `mgf-fed catch-up`, `mgf-fed test`, `mgf-fed agents`, `mgf-fed feedback-howto`, `mgf-fed explain`, `mgf-fed migrate`, `mgf-fed init-project`, `mgf-fed bench`, `mgf-fed federation-sync`, `mgf-fed validate` — all stable + accreted (new subcommands added; existing surface unchanged).

---

## Standards-layer changes that affect new code

These shipped during the span and apply to NEW work, not migration of existing:

- **NM-01..NM-04** (NAMING standard, v0.34): PyPI names + Codeberg slugs use hyphens; Python imports use dotted-namespace under `mgf.<sibling>`. Old slugs `mgf_common` and `mgf_apiprobe` were renamed to hyphen form on 2026-05-24. New consumer pyproject pins MUST use hyphens; consumer code's imports stay under `mgf.common.*` (Python identifier).
- **AGENTS** (AG-* standard, v0.34): each project ships an `AGENTS.md` pointing at the federation's canonical briefing (`mgf-fed agents`). `mgf-fed catch-up --apply` writes one if missing.
- **TIME** (TM-* standard, v0.34): `mgf.common.now()` is the canonical wall-clock + monotonic accessor. Direct `time.time()` / `datetime.utcnow()` should migrate when convenient (not urgent).
- **PERFORMANCE** (PF-* standard, v0.34): hot-path benchmarks live under `tests/perf/`; budgets in `pyproject.toml` per package. Existing consumers don't need to add perf tests.
- **OBSERVABILITY** (OB-* standard, v0.34): formalises the `bootstrap()` orchestration + observability primitives that were already shipping.
- **TS-22..TS-27** (TESTING standard, v0.40): test supervisor binding. Each project's pyproject MUST declare the 13-marker federation taxonomy + `pytest-timeout` config. `mgf-fed catch-up --apply` writes the marker block + wiring if missing (PAPER-66 + PAPER-73 closed both halves).
- **WF-01..WF-12** (WORKFLOWS standard, v0.34): Woodpecker CI on Codeberg as the federation's primary CI. `mgf-fed catch-up` audits `.woodpecker.yml` presence; consumers using GitHub Actions / other CI document the carve-out in `MGF_STANDARDS_CONFORMANCE.md`.

---

## CHANGELOG cross-references (the authoritative record)

For per-release detail beyond what's here:

- v0.35.0 — feature wave 1, naming cutover prep
- v0.36.0 — feature wave 2, `mgf.common.plugins`, `mgf.common.doctor` land
- v0.37.0 — feature wave 3, `mgf.common.idempotency`, `.rate_limit`, `.cache`, `.health` land
- v0.38.0 — pre-stability audit prep; 8 v0.1-pattern shims marked deprecated
- v0.39.0 — 50 names promoted to stable (v1.0.0); test-supervisor proposal
- v0.40.0 — test supervisor + 5 new L1 standards + naming/slug cutover
- v0.41.0 — v1.0-readiness pass + 7 deprecation removals + PUBLIC_API reshape (tag exists; never on PyPI per direct-ref blocker)
- v0.41.1 — mgf-test-supervisor PyPI publish enabled mgf-common's own PyPI publish
- v0.41.2 — PAPER-84 cross-sibling pin consistency check (🔴 blocker fix)

Each CHANGELOG entry is the per-minor source of truth; this doc consolidates the migration-relevant slice across the span.

---

## Get unstuck

If you hit something this guide doesn't cover, file a paper in `mgf-common/FEEDBACK.md`:

```
mgf-fed feedback-howto --template
```

The federation maintainer triages within the release cycle. Migration friction is exactly the kind of thing `FEEDBACK.md` exists to surface — your paper benefits every future consumer crossing the same span.
