# Changelog

All notable changes to `mgf-tele-teltonika` are documented here.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
the project follows [SemVer](https://semver.org/spec/v2.0.0.html). Per
the 0.x window ([SemVer 0.x](https://semver.org/#spec-item-4) and rule
**AP-03** from `mgf-standard/docs/standards/API_DESIGN.md`), MINOR
releases MAY break the public API. Pin tightly:

```toml
mgf-tele-teltonika = ">=0.X.0,<0.Y"   # one minor at a time
```

The release-engineering discipline that produces this changelog is in
[`mgf-standard/docs/standards/RELEASING.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/RELEASING.md).

---

## [0.1.9] - 2026-07-14

### Changed
- **Released what was stranded on `main`.** `main` had moved past `v0.1.8` while still
  declaring `0.1.8`, so the *published* `0.1.8` was different code under the same version
  number. Two things consumers never received:
  - the **Apache-2.0 relicence** (landed on main 2026-07-12; every published wheel still
    carried `License: MIT`, with no `NOTICE` — a relicence is not real until it is released);
  - the **widened `mgf-common` pin** (`<1.0`, was `<0.50`). The stale published cap
    backtracked the whole federation's co-install to `mgf-common` 0.49.2.

  `REL-13` could not see this: it compares declared version to *registry* version, and both
  said `0.1.8`. The drift was main-vs-tag content. `mgf/tools/verify_release_currency.py`
  now catches the class — *a fix that isn't released isn't shipped.*

## [0.1.8] - 2026-06-26

### Changed
- Release the **mgf-common 0.49** pin (`<0.50`) onto devpi so the full
  fleet co-installs at the 0.49 cornerstone (devpi backfill; no API change).

## [0.1.7] - 2026-06-16

### Changed
- Widened the `mgf-common` pin to `<0.48` — mgf-common 0.47 is the pure-library release (the end-user CLI moved to `mgf-fed[cli]`); the importable API is unchanged.
- Regenerated `.woodpecker` so the supervisor lane calls `mtest` (the moved `mgf-common test` frontend is gone).

## [Unreleased]

## [0.1.6] - 2026-06-09

### Added
- **AP-13**: `mgf.tele.teltonika.__version__` now present (was missing), mirrors `pyproject.toml`, in `__all__`, CI tag-coherence-gated.
- Tag-driven Codeberg publish chain (build→tag-coherence→smoke→publish→verify-codeberg) + sbom; PUBLIC_API.md/json + generator + pins; SCOPE.md; [standards] extra; PR-01 UI-forbid import-linter contract; doc-bucket charters.


Nothing yet.

---

## [0.1.5] — 2026-06-06 — federation cohort: mgf-common 0.46 walk

Walk the `mgf-common` pin ceiling `<0.46 → <0.47` to accept the
library-API-neutral `mgf-common 0.46.0` (CLI-only release: new
`federation`/`design` commands + a `doctor --standards` gate; no library
surface change).

---

## [0.1.4] — 2026-06-04 — federation cohort: mgf-common 0.45 walk

PATCH: pin widened to `mgf-common>=0.41,<0.46` to accept mgf-common 0.45
(Codeberg cutover — PKG-01..12). `mgf-*` resolve from the `codeberg-mgf`
index (PKG-06). No API change.

---

## [0.1.3] — 2026-06-01 — federation cohort: adopt mgf-common 0.44

Pin widened to `mgf-common>=0.41,<0.45` to accept the **mgf-common 0.44** line
(which extracted the standards corpus + federation contract to the
`mgf-standard` sibling; pulled in transitively). Resolves `mgf-tele-core`
**0.1.3** (which itself adopts 0.44). `FEDERATION.md` stub +
`.claude/commands/sync.md` repointed at `mgf-standard`. No API change.

---

## [0.1.2] — 2026-05-28 — federation cohort publish (mgf-common 0.42.x)

Federation cohort wave: mgf-tele-teltonika accepts **mgf-common 0.42.x** (pin widened to
`>=0.41,<0.43`) and ships to PyPI, carrying the previously-unpublished 0.1.1 work.

---

## [0.1.1] — 2026-05-28 — hostile-input safety suite + test hardening

### Added

- Adopt `mgf-test-supervisor` + TS-04 + coverage gate (85%) + tier-0 smoke.
- Hostile binary-input safety suite (12 tests incl. 2 Hypothesis fuzzers):
  lying record/IO counts, lying value-widths, oversized data-length, Codec-8E
  NX huge-payload, plus mutate/random fuzzing. The decoder withstood every
  case — for any bytes it returns a result or raises a typed `mgf.tele.core`
  error, never a raw IndexError/struct.error/OOM. Robustness now pinned.
- `USERS.md` (DOC-16).

### Notes

- Test + dev-config only; no public API or decoder-behaviour change.

---

## [0.1.0] — 2026-05-28

> **Maiden voyage** — the first per-vendor codec package in the
> `mgf-tele-*` family, extracted from PlasmaMapper's ingest path.
> PlasmaMapper is consumer #1. Builds on
> [`mgf-tele-core`](https://pypi.org/project/mgf-tele-core/) (the
> vendor-neutral seam) and never the other way around.

### Added

- **`decode_avl_packet` / `decode_codec8` / `decode_codec8e`** —
  pure decoders (`bytes → mgf.tele.core.DecodedAvlRecord[]`) for
  Teltonika **Codec 8** and **Codec 8 Extended**. Unsupported
  codecs raise `mgf.tele.core.UnsupportedCodecError`; malformed
  frames / CRC failures surface as typed
  `mgf.tele.core.TelematicsError` subclasses (rule EH-02). Codec
  12 RX (command responses), 13/14/15, and 16 are not yet
  implemented and raise `UnsupportedCodecError`.
- **`TeltonikaProvider` / `TeltonikaSessionHandle`** — the
  concrete `mgf.tele.core.TelematicsProvider` implementation for
  FMB/FMC/FMM devices: TCP IMEI handshake → receive → ack →
  close. Takes an `imei_authoriser` hook for registry-backed
  tracker authorisation. A 64 KiB frame cap (SH-04) bounds the
  unauthenticated ingest socket against a hostile
  `data_field_length`.
- **`mgf.tele.teltonika._crc.crc16_ibm`** — the CRC-16/IBM
  primitive used to validate AVL frames.
- **`mgf.tele.teltonika._packets`** — wire-packet encoders for
  round-trip testing.

### Engineering

- The decoder is a **pure function** (`bytes → records`); the
  provider owns the session lifecycle (the `mgf-tele-core`
  two-layer shape). The vendor codec depends on the neutral core,
  never the reverse — enforced by an import-linter forbidden
  contract against `plasmamapper`.
- `mgf-tele-core>=0.1,<0.2` + `mgf-common>=0.41,<0.42` runtime
  dependencies. AP-03 0.x window pin discipline applies — bump in
  lock-step with each dependency's next minor.
- PEP 420 namespace package (no top-level `mgf/__init__.py`); the
  wheel ships `src/mgf/` so `mgf.tele.teltonika`, `mgf.tele.core`,
  and `mgf.common` coexist as siblings.
