You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cd6fe0b
Browse filesBrowse the repository at this point in the historyBrowse files
fix(objectql): a bound action named like an action its target object already lists, with a different declaration, is reported at boot naming both packages; `registerAction` reports replacing another owner's handler
6
+
7
+
Clause-②: no (a warning only: no accept set narrows, no door answer moves, and no published surface gains a key; owes the seat's review of record before the queue)
8
+
9
+
-**The listing.** A top-level action bound by `objectName` to an object that already lists an action of the same name is still not attached: the object keeps serving its own declaration, as the action router does. When the two declarations differ, the boot now warns once per pair, at `kernel:ready`, naming the object, the action, the package whose declaration is served and the package whose declaration is not listed. Two packages binding different declarations of one name to a third package's object are reported the same way (the first one attached is served).
10
+
-**Not a collision.** One declaration carried twice is compared without its provenance stamps (`_packageId`, `_provenance`, the `_lock` envelope, `protection`) and without `objectName`, and is not reported: a same-stack bound action merged onto its object, or the same declaration shipped by two packages.
11
+
-**Later artifacts.** An artifact registered after the boot (a marketplace install, a ledger rehydrate) is judged once it has registered, for the pairs naming one of its packages; a pair the boot already reported is not reported again.
12
+
-**The handler.**`ObjectQL.registerAction` keys handlers by `OBJECT:ACTION`. A registration under a key another owner holds still replaces it (the last registration runs), and now warns, naming both owners: the action door runs the new owner's handler whichever declaration the object lists, and withdrawing that owner leaves the action with no handler. The same owner re-registering is silent, and so is the authored-action resync, which tears its set down first. A registration with no package is its own owner.
13
+
-**Unchanged.** Nothing is refused and no boot fails on it; the served `actions`, the router's precedence and which handler runs are as before. Measured on stock CRM, showcase and todo boots: no new warning.
14
+
-**Fix.** Rename one of the two actions, or drop the duplicate declaration.
**The 17.x minors ran under a launch-window override: a breaking change shipped as a MINOR release, not a MAJOR one.** Every published `@objectstack/*` package versions in lockstep, so the version number alone is not an upgrade-safety signal; read [Launch Window](#launch-window-minor-releases-can-contain-breaking-changes) at the end of this page before you upgrade across 17.x.
19
19
20
-
**The v18 line is a major in prerelease.** Changesets is in pre mode with the tag `next`, and `scripts/check-changeset-no-major.mjs`stands aside in pre mode, so a pull request may declare a major bump. Every release cut from `main` is the next `18.0.0-next.N` on npm's `next` tag, while `latest` stays on 17.x. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
20
+
**The v18 line has exited prerelease mode.**While Changesets was in pre mode with the tag `next`, every release cut from `main` was the next `18.0.0-next.N` on npm's `next` tag, and `scripts/check-changeset-no-major.mjs`stood aside in pre mode, so a pull request could declare a major bump. Changesets has exited pre mode, so the line's GA version is `18.0.0`, which publishes to npm's `latest` tag, and the guard again fails a pull request that declares a `major` bump. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
21
21
</Callout>
22
22
23
23
ObjectStack follows [Semantic Versioning 2.0.0](https://semver.org/) (`MAJOR.MINOR.PATCH`). The table below describes what each component means; which version a breaking change ships in depends on the line, as the callout above says.
@@ -65,7 +65,7 @@ When a feature, schema property, or API is deprecated, ObjectStack follows a str
65
65
- Code examples are updated to use the replacement
66
66
- CLI tooling may provide automated migration commands
67
67
68
-
### Phase 3: Removal (MINOR release in 17.x, the next `18.0.0-next.N`on the v18 line)
68
+
### Phase 3: Removal (MINOR release in 17.x, the next `18.0.0-next.N`during the v18 prerelease)
A["Deprecation notice — feature marked deprecated (warning emitted)"] --> B["Migration period — deprecated feature keeps working, no behavior change"]
82
-
B --> C["Removal — retired at the boundary the ADR-0087 registry records (MINOR release in 17.x, the next 18.0.0-next.N on the v18 line)"]
82
+
B --> C["Removal — retired at the boundary the ADR-0087 registry records (MINOR release in 17.x, the next 18.0.0-next.N during the v18 prerelease)"]
83
83
```
84
84
85
85
<Callouttype="warn">
86
-
**No minimum survival window.** ObjectStack does not guarantee a deprecated feature survives for a fixed number of releases — [ADR-0049](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0049-no-unenforced-security-properties.md)'s dispositions for a flagged property are enforce, `experimental`, or remove, and none of them carries a dwell time. A deprecated feature is retired at the boundary the ADR-0087 registry records for it; in the 17.x minors that removal itself landed in a MINOR release, so a MINOR bump was where to expect a removal to arrive. On the v18 line it lands in the next `18.0.0-next.N`.
86
+
**No minimum survival window.** ObjectStack does not guarantee a deprecated feature survives for a fixed number of releases — [ADR-0049](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0049-no-unenforced-security-properties.md)'s dispositions for a flagged property are enforce, `experimental`, or remove, and none of them carries a dwell time. A deprecated feature is retired at the boundary the ADR-0087 registry records for it; in the 17.x minors that removal itself landed in a MINOR release, so a MINOR bump was where to expect a removal to arrive. During the v18 prerelease it landed in the next `18.0.0-next.N`.
87
87
</Callout>
88
88
89
89
---
@@ -92,7 +92,7 @@ flowchart TD
92
92
93
93
### What Constitutes a Breaking Change
94
94
95
-
Read the **Breaking?** column, not the version number: in the 17.x minors every row below — breaking or not — shipped in a MINOR or PATCH release, and on the v18 line every row ships in the next `18.0.0-next.N`, so on neither line does the bump size tell you whether you have work to do.
95
+
Read the **Breaking?** column, not the version number: in the 17.x minors every row below — breaking or not — shipped in a MINOR or PATCH release, and during the v18 prerelease every row shipped in the next `18.0.0-next.N`, so in neither case does the bump size tell you whether you have work to do.
96
96
97
97
| Change Type | Breaking? | Version Impact (17.x minors) |
98
98
|:---|:---|:---|
@@ -114,7 +114,7 @@ Read the **Breaking?** column, not the version number: in the 17.x minors every
114
114
1.**RFC (Request for Comments)** — Breaking changes are proposed as GitHub issues with the `protocol:breaking` label.
115
115
2.**Deprecation** — The old behavior is deprecated in a MINOR release (see timeline above).
116
116
3.**Migration Guide** — A detailed migration guide is published before the removal lands, in the release notes for the version that carries it.
117
-
4.**Release** — In the 17.x minors the breaking change shipped in the next **MINOR** version, carrying a changeset entry marked `**BREAKING**`, and `scripts/check-changeset-no-major.mjs` failed a pull request that declared a `major` bump, because under lockstep one `major` would promote all 73 published packages. On the v18 line it ships in the next `18.0.0-next.N`: the guard stands aside in pre mode, so a pull request may declare a major bump. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
117
+
4.**Release** — In the 17.x minors the breaking change shipped in the next **MINOR** version, carrying a changeset entry marked `**BREAKING**`, and `scripts/check-changeset-no-major.mjs` failed a pull request that declared a `major` bump, because under lockstep one `major` would promote all 73 published packages. During the v18 prerelease it shipped in the next `18.0.0-next.N`, because the guard stood aside in pre mode and a pull request could declare a major bump. Changesets has exited pre mode, so the guard fails a `major` bump again. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
- All public exports are listed in the package's `index.ts` barrel files
176
-
- Removing an export is always a breaking change; the 17.x minors shipped it in a MINOR release, and on the v18 line it ships in the next `18.0.0-next.N`
176
+
- Removing an export is always a breaking change; the 17.x minors shipped it in a MINOR release, and during the v18 prerelease it shipped in the next `18.0.0-next.N`
177
177
- Internal modules (prefixed with `_` or in `internal/` directories) are not covered by SemVer guarantees
## Launch Window: MINOR Releases Can Contain Breaking Changes
188
188
189
189
<Callouttype="warn">
190
-
**The 17.x minors ran under this exception — read it before you upgrade across them.** Every published `@objectstack/*` package versions in **lockstep**, and in the 17.x minors a breaking change shipped as a **MINOR** release rather than burning a MAJOR, so those minors contain documented breaking changes. The v18 line is a major in prerelease: every release cut from `main`is the next `18.0.0-next.N` on npm's `next` tag, while `latest` stays on 17.x. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
190
+
**The 17.x minors ran under this exception — read it before you upgrade across them.** Every published `@objectstack/*` package versions in **lockstep**, and in the 17.x minors a breaking change shipped as a **MINOR** release rather than burning a MAJOR, so those minors contain documented breaking changes. During the v18 prerelease every release cut from `main`was the next `18.0.0-next.N` on npm's `next` tag; Changesets has exited pre mode, so the line's GA version is `18.0.0`, which publishes to npm's `latest` tag. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
191
191
</Callout>
192
192
193
193
### Which surfaces this covers
194
194
195
195
**All of them.** It was not scoped to an experimental corner or a pre-release channel: all **73** packages published from this repository belong to a single Changesets `fixed` group, so they share one version number and one policy. No published surface was exempt.
196
196
197
-
The convention was enforced rather than informal — `scripts/check-changeset-no-major.mjs` failed a pull request that introduced a `major` bump, because under lockstep a single `major` on one package would promote the entire stack. Changesets is now in pre mode with the tag `next`, and the guard stands aside in pre mode, so a pull request on the v18 line may declare a major bump.
197
+
The convention was enforced rather than informal — `scripts/check-changeset-no-major.mjs` failed a pull request that introduced a `major` bump, because under lockstep a single `major` on one package would promote the entire stack. During the v18 prerelease Changesets was in pre mode with the tag `next` and the guard stood aside, so a pull request on the v18 line could declare a major bump. Changesets has exited pre mode, and the guard fails a `major` bump again.
198
198
199
199
### What this means for an upgrade
200
200
201
201
-**Do not read a MINOR bump as safe to take unattended.** Read the [release notes](/docs/releases) for the version you are moving to: they lead with breaking changes and carry the migration steps.
202
202
-**Pin exact versions** instead of caret ranges if you cannot review each MINOR before it lands.
203
203
-**Diff your own metadata** across the upgrade with `os diff <before> <after> --breaking-only`.
204
204
205
-
MAJOR releases do still happen — 17.0.0 was cut precisely because its breaking density was too high to carry `^16.x` consumers across on a caret range, and the v18 line is a major in prerelease — but in the 17.x minors an individual breaking change did not, on its own, force one.
205
+
MAJOR releases do still happen — 17.0.0 was cut precisely because its breaking density was too high to carry `^16.x` consumers across on a caret range, and the v18 line is the next one — but in the 17.x minors an individual breaking change did not, on its own, force one.
206
206
207
207
### When it stops applying
208
208
209
-
The tables and deprecation timeline above state this rule for the 17.x minors directly, beside what the v18 line does. Classic SemVer — where a breaking change once again requires a MAJOR — is the settled form the project returns to once the launch window closes: the window closes at GA, and strict SemVer resumes from that point. **For the 17.x minors, this section was the operative rule wherever any part of this page disagreed.** For the `18.0.0-next.N` prereleases, the operative rule is [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
209
+
The tables and deprecation timeline above state this rule for the 17.x minors directly, beside what the v18 prerelease did. Classic SemVer — where a breaking change once again requires a MAJOR — is the settled form the project returns to once the launch window closes: the window closes at GA, and strict SemVer resumes from that point. **For the 17.x minors, this section was the operative rule wherever any part of this page disagreed.** For the `18.0.0-next.N` prereleases, the operative rule is [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
0 commit comments