From d991627575cad6ddf7274c8a78d9f39d43205d06 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 16:00:23 +0000 Subject: [PATCH] docs(changeset): scope the `os lint --json` `conversions` guarantee to the project-lint exits (#14015) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The merged #13741 changeset told consumers `conversions` is "always an array on `os lint --json` … so it can be read unconditionally". Re-censused on `main`: `lint.ts` has four `--json` exits and only two of them carry the key. The two `--eval` exits — the eval report and the `--generator` load failure — publish no `conversions`, so a consumer who believed the sentence and wrote `payload.conversions.length` gets a `TypeError` on that path. Release notes compile from `.changeset/*.md` centrally at release time, so this sentence was scheduled to become a published statement about a machine-readable contract. Narrow it now, in the unreleased file, to say which exits carry the key and which do not. Wording only — no contract moves. Making the `--eval` exits emit `conversions` would widen a published payload on paths that never carried the key; that needs its own card and an at-tier contract review. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza --- .changeset/cli-lint-conversion-notices.md | 29 ++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.changeset/cli-lint-conversion-notices.md b/.changeset/cli-lint-conversion-notices.md index 2828cc056f..dcb274f9a6 100644 --- a/.changeset/cli-lint-conversion-notices.md +++ b/.changeset/cli-lint-conversion-notices.md @@ -52,8 +52,9 @@ and their metadata stopped loading. | face | before | after | | --- | --- | --- | | console (`os lint`) | nothing | one `⚠` line per notice: the path, `'from'` → `'to'`, the conversion id, and the protocol major it retires in | -| `os lint --json` | no such key | `conversions`: the same structured notices, unconditionally present | -| `os lint --json`, thrown / caught | no such key | what the run had computed — `[]` for a throw at load | +| `os lint --json` (project lint) | no such key | `conversions`: the same structured notices, present on every exit of this mode | +| `os lint --json` (project lint), thrown / caught | no such key | what the run had computed — `[]` for a throw at load | +| `os lint --eval --json` | no such key | **still no such key** — out of scope here, see below | The console wording is `compile.ts`'s, verbatim, so an author who runs two of the three commands over one tree is told the same thing in the same words. The @@ -63,18 +64,30 @@ consumer reads all three authoring commands the same way. ## What a consumer should know -✅ `conversions` is **always an array** on `os lint --json`, success or -failure, so it can be read unconditionally. Each entry keeps its structured -`conversionId`, `surface`, `from`, `to`, `path`, `toMajor` and `retiresIn` -fields, so a CI job can gate on `retiresIn` without a second run. +✅ `conversions` is **always an array** on the **project-lint** `--json` +payloads — the report exit and the caught-error exit, success or failure — so +a consumer of plain `os lint --json` can read it unconditionally. Each entry +keeps its structured `conversionId`, `surface`, `from`, `to`, `path`, +`toMajor` and `retiresIn` fields, so a CI job can gate on `retiresIn` without +a second run. + +⛔ **`os lint --eval --json` does not carry the key**, and this change did not +add it there. `--eval` scores a generation corpus instead of loading the +project, so it never reaches the conversion layer; both of its JSON exits — +the eval report, and the `--generator` load failure — publish no `conversions`. +That is the whole exception: `lint.ts` has four `--json` exits, the two +project-lint ones carry the key and the two `--eval` ones do not. A consumer +that runs both modes must guard the key on the `--eval` path (or branch on the +mode it asked for) — `payload.conversions.length` is a `TypeError` there. ⛔ `conversions: []` does **not** mean "this tree converts nothing" on the caught-error payload — it means the run stopped before the conversion layer ran. A config that fails to load reports `[]` by construction. Read the `error` key to tell the two apart. -⛔ A consumer asserting an exact key set on `os lint --json` must add -`conversions` to it. No existing key changed: `total`, `errors`, `warnings` +⛔ A consumer asserting an exact key set on the project-lint +`os lint --json` payload must add `conversions` to it; the `--eval` key sets +are unchanged. No existing key changed: `total`, `errors`, `warnings` and `suggestions` count exactly what they counted before, and exit codes are untouched (errors still exit 1).