Filed by the domain:metadata PM seat from the #8296 dev's closing report, which falsified a PM mechanism assumption. Docs-only follow-up; the code that landed is correct and is not in question.
The bump is right — the annotation is missing
.changeset/filter-formula-field-refusal.md landed with edff010c (PR #8369) declaring minor for @objectstack/metadata-protocol and @objectstack/objectql. It is still unconsumed, so it can be edited.
minor is correct and should not change. scripts/check-changeset-no-major.mjs is a launch-window guard whose header states the convention verbatim — "During the launch window we ship breaking changes as minor (pre-1.0 semantics …)" — because every publishable package sits in the Changesets fixed lockstep group, so a single major promotes the whole stack (~70 packages).
What is missing is the other half of that convention.
Why this one is genuinely breaking
#8296 made a where on a virtual formula field answer 400 INVALID_FIELD instead of 200 with zero rows, at both doors. The engine half runs inside lowerWhereFilterArray, so a previously-succeeding call to engine.find / findOne / count / aggregate / update / delete now throws. That is a public API surface and six verbs.
The closest precedent says so explicitly. The dev enumerated how the sibling axes actually shipped, and they did not ship uniformly:
| card | axis | bump |
|---|
| #6994 | sort, ingress | metadata-protocolminor |
| #6674 | search | metadata-protocol / spec / lint all patch |
| #7095 | sort, ENGINE seam | @objectstack/objectql MAJOR, ! title |
#7095 is this PR's exact shape — the engine seam, a previously-succeeding call beginning to throw — and it shipped majorbecause of that. It predates the no-major guard and is currently masked by the RC exemption (.changeset/pre.json, mode pre, tag rc). So the guard, not the precedent, decides the bump; but the precedent is evidence that the breakingness is real and was previously considered worth a major.
The repo already has the answer
#6099 (closed) is the same shape on the objectui side: the generated console changeset carried zero annotation for breaking changes because the digest only recognises the major declaration level, while objectui declares breaking changes inside the v17 window as minor + 正文标注 (body annotation). That is the established convention, and it is the half #8296's changeset is missing.
The ask
Add an explicit breaking-change annotation to .changeset/filter-formula-field-refusal.md's body, in whatever marker form the release digest reads, so the change is classified correctly when pre-mode exits and the notes are compiled.
⚠️Do not change the bump to major — that requires the allow-major label and would promote the entire stack. The bump is not the defect.
The changeset already carries the remedy ("denormalise the value onto the object … and filter that") and a migration instruction ("grep your saved reports, flows, dashboards and view filters for a filtered field whose object declares it as a formula"). Substantively the guidance is there; what is absent is the marker that lets tooling separate a breaking minor from an ordinary one.
Scope note
⛔ This card is about #8296's changeset only. Whether the framework side enforces the #6099 convention generally — i.e. whether any gate requires a breaking minor to carry the annotation — is a broader tooling question and is not claimed here. If a taker finds there is no such gate, file that separately rather than widening this card; #8410 is already open in adjacent territory (dispatch-gates.mjs does not derive Check Changeset for .changeset/ paths).
Related
#8296 · #8369 (edff010c) · #7095 (the engine-seam precedent that shipped major) · #6994 · #6674 · #6099 (the minor + body-annotation convention) · #8410
Filed by the
domain:metadataPM seat from the #8296 dev's closing report, which falsified a PM mechanism assumption. Docs-only follow-up; the code that landed is correct and is not in question.The bump is right — the annotation is missing
.changeset/filter-formula-field-refusal.mdlanded withedff010c(PR #8369) declaringminorfor@objectstack/metadata-protocoland@objectstack/objectql. It is still unconsumed, so it can be edited.minoris correct and should not change.scripts/check-changeset-no-major.mjsis a launch-window guard whose header states the convention verbatim — "During the launch window we ship breaking changes asminor(pre-1.0 semantics …)" — because every publishable package sits in the Changesetsfixedlockstep group, so a singlemajorpromotes the whole stack (~70 packages).What is missing is the other half of that convention.
Why this one is genuinely breaking
#8296 made a
whereon a virtualformulafield answer400 INVALID_FIELDinstead of200with zero rows, at both doors. The engine half runs insidelowerWhereFilterArray, so a previously-succeeding call toengine.find/findOne/count/aggregate/update/deletenow throws. That is a public API surface and six verbs.The closest precedent says so explicitly. The dev enumerated how the sibling axes actually shipped, and they did not ship uniformly:
metadata-protocolminormetadata-protocol/spec/lintall patch@objectstack/objectqlMAJOR,!title#7095 is this PR's exact shape — the engine seam, a previously-succeeding call beginning to throw — and it shipped
majorbecause of that. It predates the no-major guard and is currently masked by the RC exemption (.changeset/pre.json, modepre, tagrc). So the guard, not the precedent, decides the bump; but the precedent is evidence that the breakingness is real and was previously considered worth a major.The repo already has the answer
#6099 (closed) is the same shape on the objectui side: the generated console changeset carried zero annotation for breaking changes because the digest only recognises the
majordeclaration level, while objectui declares breaking changes inside the v17 window asminor+ 正文标注 (body annotation). That is the established convention, and it is the half #8296's changeset is missing.The ask
Add an explicit breaking-change annotation to
.changeset/filter-formula-field-refusal.md's body, in whatever marker form the release digest reads, so the change is classified correctly when pre-mode exits and the notes are compiled.major— that requires theallow-majorlabel and would promote the entire stack. The bump is not the defect.The changeset already carries the remedy ("denormalise the value onto the object … and filter that") and a migration instruction ("grep your saved reports, flows, dashboards and view filters for a filtered field whose object declares it as a
formula"). Substantively the guidance is there; what is absent is the marker that lets tooling separate a breakingminorfrom an ordinary one.Scope note
⛔ This card is about #8296's changeset only. Whether the framework side enforces the #6099 convention generally — i.e. whether any gate requires a breaking
minorto carry the annotation — is a broader tooling question and is not claimed here. If a taker finds there is no such gate, file that separately rather than widening this card; #8410 is already open in adjacent territory (dispatch-gates.mjsdoes not deriveCheck Changesetfor.changeset/paths).Related
#8296 · #8369 (
edff010c) · #7095 (the engine-seam precedent that shippedmajor) · #6994 · #6674 · #6099 (theminor+ body-annotation convention) · #8410