# v2.4

## Summary

- **Fix the reported version.** An installed distribution is now looked up
  rather than assumed, so `rosotacom --version` reports the real version under
  both published names (`rosotacom-dev` from this fork, `rosotacom` upstream).
  Up to 2.3 every installed `rosotacom-dev` reported `0+unknown`, which made a
  version check against a pin impossible and produced an unbuildable OTA source
  bundle.
- **Publish a development channel.** Every commit that lands on the development
  branch with green CI is published as a `X.Y.devN` pre-release. Consuming this
  package no longer means waiting for a release decision. `pip` ignores
  pre-releases unless one is pinned exactly, so the stable line is unaffected.
- **Stop duplicating packaging metadata.** The source bundle `ota-smoke` builds
  when it runs from an installation derives its name, version, dependencies and
  entry points from the installed distribution. The hand-written copy it used
  before had drifted: `mcap` and `Pillow` were missing, so a peer prepared this
  way imported fine and then failed inside the first MCAP or image code path.
- **`ota-smoke --install-mode pin`.** Install a published release on each peer
  instead of staging a source tree, so the rehearsal runs the artefact that
  ships and can catch a packaging defect before a target machine does. The run
  manifest records the mode and version the peers ran.
- **`rosotacom resources path` covers `package` and `examples`**, which is how
  pin mode remaps project config roots onto the peer's installation.

## Compatibility And Migration

- `ota-smoke` behaves as before unless `--install-mode pin` is passed.
- The OTA deployment state file (`ota-deployment.yaml`) is now `schema_version:
  2` and carries the install mode. State files written by an older version are
  rejected; they are per-run artifacts, so start a new run.
- Consumers pinning `rosotacom-dev==2.3` should move to `2.4` to get a usable
  `--version`.

## Validation

- `just lint`
- `just typecheck`
- `just test-unit`
- `just test-contract`
- `just docs`
- `just package`
- `just test-e2e-smoke`
- `tests/contract/test_ota_source_bundle.py` fails if the bundle metadata ever
  diverges from `pyproject.toml` again.
