# Changelog

All notable changes to `mgf-logship` 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 (rule **AP-03** from `mgf-standard/docs/standards/API_DESIGN.md`), MINOR
releases MAY break the public API. Pin tightly:

```toml
mgf-logship = ">=0.X.0,<0.Y"
```

---

## [0.1.8] - 2026-06-26

### Changed
- Adopt **mgf-common 0.49** — widen the pin to `<0.50` (the framework-neutral
  Svix webhook HMAC primitive `mgf.common.webhooks` + the AP-14 identity /
  lifecycle / doctor public seams; additive). Republished so consumers that
  pin `mgf-common>=0.49` (mgf-fed, mgf-fastapi) can resolve `mgf-logship`.

## [Unreleased]

### Security
- **Collector body cap (SC / DoS).** `/ingest` and `/stats` now read the request
  body through a hard size cap (`_MAX_BODY_BYTES`, 64 MiB) — a Content-Length
  fast-reject plus a streamed byte cap — returning `413` instead of buffering an
  unbounded body into the central log host's memory.

## [0.1.7] - 2026-06-25

### Changed
- Widen the `mgf-common` pin to `<0.49` — adopt **0.48** (the `retry` + public `io.atomic_write` primitives + the L3 cornerstone). Cohort pin-walk for the 0.48 minor; no code changes.

## [0.1.5] - 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]

### Added
- **Collector gateway → OpenObserve** (logging program **L1**; realizes design D4 "ship + protocol now, stub the server"). The store-now stub becomes a pluggable-backend gateway: the inbound NDJSON wire protocol is **unchanged**, and records/stats now forward to **OpenObserve** (`OpenObserveBackend`) with the local sqlite as a durable **spool** on outage (`SpoolingBackend`, fail-open — a backend hiccup never breaks a shipping app, never drops a record), drained by `POST /admin/flush` + an optional periodic flusher. `SqliteBackend` remains the store-now path. Backend choice, retention (global default **30d**), and auth are layered config (`CollectorConfig.from_env`, `MGF_LOGSHIP_*`). `create_collector_app(db_path=, token=)` stays back-compatible.

### Changed
- `httpx` moves into the `[collector]` extra; the shipper core (`_shipper` + `_protocol`) stays **stdlib-only** — import-linter now pins "core: no fastapi/httpx" (only the collector gateway may use them).

---


## [0.1.4] — 2026-06-08 — depth-audit close-out (public API + docs)

### Added
- `mgf.logship.__version__` (AP-13); CI tag-coherence asserts it.
- `PUBLIC_API.md` + `PUBLIC_API.json` + generator + CI pins (AP-10/11, DOC-01/08/09).
- Missing federation docs: DEPS, FEEDBACK, FEDERATION, SECURITY, docs/claude/CLAUDE,
  SCOPE + doc buckets; import-linter contracts + tag-driven publish pipeline + sbom (earlier batches).

### Changed
- `_shipper` docstring documents the collector/wire replaceability recipe (DP-08).
- Declined (CFM-04 §3): AP-14 (consumer-fixture import-linter).

## [0.1.3] — 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.2] — 2026-06-04 — federation cohort: mgf-common 0.45 walk

PATCH: pin widened to `mgf-common>=0.42,<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.1] — 2026-06-01 — federation cohort: adopt mgf-common 0.44

PATCH: 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). `FEDERATION.md` stub +
`.claude/commands/sync.md` repointed at `mgf-standard`. No API change.

---

## [0.1.0] — 2026-05-28 — first cut (unified-logging Wave 5)

The Layer-B shipper + protocol + stub collector (mgf-common unified-logging
design §6, decision D4).

### Added

- **`LogShipper`** — a fail-open, bounded `logging.Handler` that batches
  canonical mgf-common `LogRecord` JSON (OB-10) and `POST`s NDJSON batches to a
  collector. Redacts every record before it leaves the process (design §8);
  bounded queue (oldest dropped on overflow, `dropped_count`); background daemon
  flush thread; a down/slow collector never blocks or crashes the app
  (`shipped_count` / `failed_count` counters). Optional periodic `LogStats`
  shipping via `stats_provider`. Stdlib-only transport (`urllib`).
- **Wire protocol** (`mgf.logship` / `mgf.logship._protocol`) —
  `SHIP_PROTOCOL_VERSION` + endpoint paths (`/ingest`, `/stats`, `/health`) +
  `X-Logship-*` headers + NDJSON framing (`encode_ndjson` / `decode_ndjson`).
  HTTP + NDJSON so a Zig/TS shipper can interoperate; the `LogRecord` line is
  carried verbatim (cross-language byte-identity preserved end-to-end).
- **`mgf.logship.collector.create_collector_app`** — a store-now stub collector
  (FastAPI + stdlib sqlite3), behind the `[collector]` extra. Token-gated
  writes; persists logs + stats; no analysis/UI (a later program).

Depends on `mgf-common>=0.42` (canonical `LogRecord` + `LogStats` + `Redactor`).
