|
| 1 | +# API Deprecation Policy |
| 2 | + |
| 3 | +How the HTTP API (`/api/*`), CLI flags (`cursor-chat-export`), and shared JSON response fields are deprecated and removed. Complements the [Versioning](../README.md#versioning) section and [CHANGELOG.md](../CHANGELOG.md). |
| 4 | + |
| 5 | +## Pre-1.0 posture |
| 6 | + |
| 7 | +While the project is at `0.x.y`, **breaking changes may land in any minor release** without a prior deprecation cycle. Deprecations are still recorded in the changelog when practicable, but there is no guarantee of advance notice before removal. Pre-1.0, workflow steps 2–4 (CLI help text, response headers, server logs) are **encouraged but optional**; step 1 (changelog) applies when practicable. After `1.0.0`, the workflow below applies in full. |
| 8 | + |
| 9 | +## Deprecation workflow |
| 10 | + |
| 11 | +When an endpoint, parameter, response field, or CLI flag is scheduled for removal: |
| 12 | + |
| 13 | +1. **CHANGELOG** — Add an entry under `### Deprecated` naming the surface, its replacement (if any), and the planned removal version. |
| 14 | +2. **CLI help** (flags only) — Add `(deprecated, use <replacement>)` to the flag's argparse help string. |
| 15 | +3. **Response headers** — Deprecated HTTP endpoints and parameters emit deprecation headers on every affected response (see [Header format](#header-format)). When the first endpoint is deprecated, implement via a small shared Flask helper so handlers stay consistent with the policy. |
| 16 | +4. **Server log** — Route handlers log `logging.warning()` with the deprecated symbol and recommended replacement. |
| 17 | +5. **Removal** — Remove no earlier than **one minor version** after the deprecation was announced (e.g. deprecated in `1.2.0`, removable from `1.3.0`). Document under `### Removed` in the changelog. |
| 18 | + |
| 19 | +## Header format |
| 20 | + |
| 21 | +This project currently documents a **simplified custom format** for pre-1.0. It does not match [IETF `Deprecation`](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header) (HTTP-date value, not `true`) or [RFC 8594](https://www.rfc-editor.org/rfc/rfc8594) (separate `Sunset` and `Link` headers). Adopt the standards-aligned form below when the shared Flask helper lands or at `1.0.0`. |
| 22 | + |
| 23 | +**Current (custom, pre-1.0):** |
| 24 | + |
| 25 | +```http |
| 26 | +Deprecation: true; sunset=2026-09-01 |
| 27 | +``` |
| 28 | + |
| 29 | +- `sunset=` — ISO 8601 calendar date (UTC) when removal is scheduled, embedded in the `Deprecation` value. |
| 30 | + |
| 31 | +**Target (standards-aligned)** — emit as **separate headers** from Flask: |
| 32 | + |
| 33 | +```http |
| 34 | +Deprecation: Tue, 01 Sep 2026 00:00:00 GMT |
| 35 | +Sunset: Tue, 01 Sep 2026 00:00:00 GMT |
| 36 | +Link: <https://github.com/cppalliance/cppa-cursor-browser/blob/HEAD/CHANGELOG.md>; rel="deprecation" |
| 37 | +``` |
| 38 | + |
| 39 | +Migration notes use a separate **`Link`** header (RFC 8288), not a `link=` parameter on `Deprecation`. |
| 40 | + |
| 41 | +Clients should treat any deprecation signal as a prompt to migrate before the sunset date. |
| 42 | + |
| 43 | +## Surfaces covered |
| 44 | + |
| 45 | +| Surface | Signals | |
| 46 | +|---------|---------| |
| 47 | +| HTTP endpoint or parameter | Deprecation headers, changelog entry, server log | |
| 48 | +| JSON response field | Changelog entry; field remains until removal (no in-band signal today; future: `X-Deprecated-Fields` header or `_deprecated` envelope key) | |
| 49 | +| CLI flag | `(deprecated)` in `--help`, changelog entry | |
| 50 | + |
| 51 | +## Removal documentation |
| 52 | + |
| 53 | +Removals go under `### Removed` in [CHANGELOG.md](../CHANGELOG.md): what was removed, which version deprecated it, and the migration path. |
0 commit comments