From d7feeed342a741e56164e09fdf1059bf53d56e4d Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 09:53:27 +0000 Subject: [PATCH] docs(releases): 18.3.0 names the fail-closed type-mismatch refusal it shipped without a CHANGELOG entry, and the cut runbook regenerates the version PR first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 18.3 page lists #29923's narrowing under 需手动处理 with the refusal it serves (type-mismatch + params.outcome 'fail-closed', 18.2.0 warned then refused every write -> 18.3.0 refuses at publish) and the rename on main (#29953). docs/releases-maintenance.md gains a numbered cut order: list the changesets main gained since the version PR's branch point and refresh before merging; confirm zero pending changesets after the cut and name any leak in the curated page. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01WGufziWtqgnT2f4C6ThaSM --- content/docs/releases/v18/18-3.mdx | 26 ++++++++++++++++-- docs/releases-maintenance.md | 42 +++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/content/docs/releases/v18/18-3.mdx b/content/docs/releases/v18/18-3.mdx index 14eba4f41b9..0c4fabae3a2 100644 --- a/content/docs/releases/v18/18-3.mdx +++ b/content/docs/releases/v18/18-3.mdx @@ -121,7 +121,10 @@ Three notes for reading the 18.3.0 CHANGELOGs: password reset ends leaves a revocation trail (`7b2bb66`, #29921); and an organization administrator's refused assignment removal answers the same for a row it cannot read as for a missing one (`72d7db0`, #29932). Each is - in the [upgrade checklist](#upgrade-checklist) where it applies. + in the [upgrade checklist](#upgrade-checklist) where it applies, and the + breaking one is also listed under + [需手动处理](#metadata-the-build-lint-and-save-doors-now-refuse) with the + refusal it serves. - **Each entry names the commit that added its changeset**, and this page cites the same commits. A commit that added several changesets is named by each of them: the 1,379 entries name 1,300 commits. @@ -280,7 +283,26 @@ to meet. #### Metadata the build, lint and save doors now refuse -8 entries. +8 entries, and one more that 18.3.0 ships with no entry in its CHANGELOGs +(see [the release facts](#release-facts-as-measured)): + +- **Not in the 18.3.0 CHANGELOGs.** A text or boolean field ordered against + a number in a predicate that fails closed is refused. The sites are a + validation rule's `condition` and `when` (nested rules included), a + field's `requiredWhen` and `readonlyWhen`, an option's `visibleWhen`, and + a hook's `condition`. 18.2.0 published `record.name > 5` on a text field + with an `expression-invalid` warning, then refused every write whose `name` + was not numeric text. 18.3.0 refuses it at `os validate`, `os build`, the + object save door and publish, as `expression-invalid` at `severity: + error`. The refusal it carries is `type-mismatch` with + `params.outcome: 'fail-closed'`, and the MCP `validate_expression` tool + answers the same for `site: 'validation'`. Write `size(...)` for a length, + compare a number field for a value, or cast with `double(...)` only when + every value is numeric text. The upgrade guide entry is + `validation-type-mismatch-refused`. After 18.3.0, `main` serves this + refusal under its own code, `type-mismatch-fail-closed`, with no `outcome` + param (#29953); the next release's notes list that rename (`4c2cd29`, + #29923) - `os validate` and `os build` refuse a seed record value the seed load would refuse, with the load's own code and sentence, located at the record's field (for #27259) (`99aeee6`, #27600) - A scaffold into the current directory refuses, writing nothing, when a template file would overwrite one already there (for #29134) (`ad224b7`, #29267) diff --git a/docs/releases-maintenance.md b/docs/releases-maintenance.md index 8aafcaad5d7..d4e8e0607da 100644 --- a/docs/releases-maintenance.md +++ b/docs/releases-maintenance.md @@ -231,10 +231,44 @@ never one you supply (ADR-0125 D1/D2). ⛔ **Actions → Release → Run workflo all, and left unchecked it starts the repair lane for a publish that died partway — checked, it starts the bookkeeping lane described next. -**First, check #4935 is current** (#11233). It is regenerated on a 6-hourly schedule -rather than on every push, so at cut time it can be up to one refresh window behind -main — i.e. it may not yet carry a changeset that landed in the last few hours. -Compare its head against `main` and, if it is behind, **Actions → Release → Run +The cut, in order (each step is explained below): + +1. **Regenerate the Version Packages PR against current `main` right before you + merge it.** List the changesets `main` gained since the PR's branch point: + + ```bash + git fetch origin main changeset-release/main + base=$(git merge-base origin/main origin/changeset-release/main) + git diff --name-only --diff-filter=A "$base" origin/main -- .changeset/ | grep -v README + ``` + + Anything listed is code the cut would ship without a CHANGELOG entry: + refresh (below), wait for its CI, and run the list again before you merge. +2. **Wait for a nearer `CI` run** before approving the publish (below). +3. **Confirm the version commit left zero changesets pending.** The Release + run that queues the publish says so in its job summary (`Changesets:`), + or warns with each changeset it did not consume; on a full clone, + `node scripts/release-pending-publish.mjs unconsumed --version-commit SHA + --version VERSION` answers the same. If it is not zero, name each one in + the curated release page, and list a breaking one under 需手动处理 with + the refusal it serves. Never edit the generated `CHANGELOG.md` files or the pending + changesets: the next cut consumes them and `annotate-shipped` marks them + `**Shipped in VERSION**`. + +Why step 1 is a step and not a check: `main` takes a changeset-bearing landing +about every twenty minutes, so a check that refused a stale Version Packages PR +would refuse nearly every cut (the measurement is in +`scripts/release-pending-publish.mjs`, under `annotate-shipped`). 18.3.0 shows +the leak it leaves: #26517 was refreshed at 13:39Z from `40a35ded` and merged +at 14:44Z without another refresh, five landings behind, so four changesets +(one of them breaking, #29923) shipped with no entry in its CHANGELOGs +(#29957). + +**First, check the Version Packages PR is current** (#11233). It is regenerated on a +6-hourly schedule rather than on every push, so at cut time it can be up to one +refresh window behind main — i.e. it may not yet carry a changeset that landed in +the last few hours. Compare its head against `main` (step 1's list) and, if it is +behind, **Actions → Release → Run workflow** with **`refresh_version_pr` checked**, which runs the bookkeeping lane only: no audit, no publish, and no deployment parked at the `release` environment. Wait for the refreshed PR's CI, then merge it. That merge is still the decision to