@objectstack/types 17.0.0-rc.2 → 17.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,374 @@
1
1
  # @objectstack/types
2
2
 
3
+ ## 17.0.0-rc.4
4
+
5
+ ### Minor Changes
6
+
7
+ - 28ad90e: feat(types,cloud-connection,lint,cli): ADR-0120 17.x 收尾 —— `isolated` 安装期姿态硬门(D5e)、D5c 重拼写 advisory、成文契约扫荡与三姿态 conformance (#5081)
8
+
9
+ ADR-0120 17.x 波的第三块,也是最后一块。前两块已在 main 上:#5212(driver 侧
10
+ D3+D4 —— `COALESCE(organization_id, '__global__')` 物化、drift 两侧同步、重复预检)
11
+ 与 #5208(spec 词汇 `'organization'` + D5a/D5b lint)。本次补齐三件事:安装期的
12
+ 姿态决策点、剩余的成文契约、以及把「一个 app 包跑遍三种姿态」从假设变成测试。
13
+
14
+ **D5e —— 装进 `isolated` 环境时的硬门。** 词汇本身是姿态无关的:作者说的是业务
15
+ 边界(`'organization'` 一个组织一份 / `'global'` 整个安装一份),没有任何索引形状
16
+ 读姿态。唯一的残留在一个方向上:`isolated` 下组织就是**不同客户**,此时 app 业务
17
+ 对象上的 `'global'` 唯一既跨客户过度约束,又变成跨客户的存在性预言机(S10/S14)。
18
+ 维护者裁定这是**硬门而非 advisory**:把带 `'global'` 唯一(非 `sys` 对象)的 app
19
+ 装进 `isolated` 环境会**停下来并逐索引列出**,安装者(通常是 AI agent)要么确认它
20
+ 确实是平台级的,要么改写为 `'organization'`;确认按 ADR-0104 attestation 风格
21
+ 留痕在安装清单里(`InstalledManifestEntry.globalUniqueAttestation` —— 确认了什么、
22
+ 谁确认的、何时、在哪个姿态下问的),**之后不复问**。
23
+
24
+ - 停下的安装**什么都不留**:先于 hot-register 和任何 ledger 写入,所以作者改完
25
+ 元数据可以直接重试,不需要先卸载。
26
+ - 逐索引确认是有牙齿的:`confirmGlobalUniques` 收 `true` 或明确的 id 数组,只确认
27
+ 其中一条仍会在剩下的那条上停住。
28
+ - 升级引入的**新**约束会被问,老的答案继续算数。
29
+ - 另一个姿态下给出的确认**不算同意** —— `isolated` 那个问题在 `single` 下从未被
30
+ 问过,所以按「未确认」处理(唯一不会静默放行跨客户约束的方向)。
31
+ - ⛔ **永不做成启动期告警**(#4884 纪律)。boot 时的 rehydrate 不评估此门;门够不到
32
+ 的两类存量 —— 门禁上线前的安装、装后姿态变更的环境 —— 由 `os doctor` 与
33
+ `os migrate plan` 的 advisory 形态覆盖。
34
+
35
+ 判定里有三条是承重的,别「简化」掉:声明索引上的裸 `unique: true` **算**(D1 说它
36
+ 就是 `'global'` 的位置式拼写,排除它等于让整个 17.x 可以靠拼写绕过);字段级
37
+ `true` **不算**(它是 `'organization'`,永久合法);`sys_`/`base_` 对象**不算**
38
+ (S5 那批引擎幂等键天然就是平台级的,每次安装都问一遍就是 #4884 的误报类)。
39
+
40
+ CLI: `os package install` 新增 `--confirm-global-uniques`,并把 409 渲染成可读的
41
+ 逐条清单而不是一句 "Install failed (409)"。
42
+
43
+ **D5c —— 遗留手写组织复合索引的 advisory。** 新规则
44
+ `unique/legacy-organization-composite`:声明的唯一索引自己列出了组织列
45
+ (`{ fields: ['name','organization_id'], unique: true }`)—— 这是词汇出现之前手写
46
+ per-organization 的写法。它读起来像「每组织唯一」,物化出来却是普通复合索引,而
47
+ SQL UNIQUE 是 NULL-distinct 的:组织列为 NULL 的行上它**什么都不约束**(#5030),
48
+ 在单组织部署上那就是每一行。改写成 `unique: 'organization'`(`fields` 原样保留,
49
+ driver 会把已列出的组织列**就地**变成 NULL-safe 形式)正是补上这个洞的动作。
50
+ **永远只是 advisory,永远不自动修**:老拼写永久合法、零强制 drift,而 opt-in 是
51
+ 真实的物理收紧,要走 D4 的 `recreate_index` + 重复预检。
52
+
53
+ **D6 —— 成文契约扫荡。** `content/docs/data-modeling/indexing.mdx` 的
54
+ §Two ways to say "unique" 全节按新词汇重写(含 `os:check` 代码块);
55
+ `content/docs/protocol/objectql/schema.mdx` 的 §Uniqueness and tenancy 重写为
56
+ §Uniqueness and scope —— 其中那句「单租户部署不受影响,租户列是常量,复合索引
57
+ 退化为单列索引」是 #5030 **证伪过的原话**,现已替换为 D3 的 NULL-safe 事实;
58
+ `content/docs/deployment/cli.mdx` 的 `replace_unique_index` / `recreate_index`
59
+ 条目补上 NULL-safe 形状与重复预检;`content/docs/references/**` 经
60
+ `gen:schema && gen:docs` 再生成,未手改。
61
+
62
+ 按 ADR-0120 Resolved #2 的非规范性引导(官方示例/脚手架/生成器在新代码中输出
63
+ 显式拼写),`skills/objectstack-data/**` 的索引与校验规则整体扫过:声明索引一律
64
+ 说清 scope,并新增一节完整讲 `'organization'` 的 NULL-safe 语义与「永远不写姿态」。
65
+ 顺带修掉那里长期使用的 `tenant_id` —— 平台的列叫 `organization_id`。
66
+ `examples/**`、`create-objectstack` 模板与 `os generate` 经核查**根本没有声明任何
67
+ 唯一约束**,故无可扫;这是核查结论,不是遗漏。
68
+
69
+ **三姿态 conformance(ADR §Acceptance tests)。** 同一个 fixture app 在
70
+ `single | group | isolated` 三姿态下启动,逐 S 行用**真实的违规插入**断言 enforcement
71
+ (S1/S2/S3/S4/S5/S6/S7/S8/S9/S11/S12),并逐姿态捕获物化出的索引键,断言三者
72
+ **逐字节相同** —— 「没有任何索引形状读姿态」这句话一旦有两者不同就是假的。相同性
73
+ 断言配了一条正向断言(对着期望的键形状),这样「三次都什么都没建」不会读成「一致」。
74
+ 外加 ADR 只要的那一条 transition smoke:在 `single` 下建库、`isolated` 下重新打开,
75
+ drift op 为零。
76
+
77
+ 对既有部署的影响:除新增的安装期确认外,本次不改变任何已有物化行为。字段级
78
+ `unique: true` 一如既往合法。
79
+
80
+ - 64cd010: fix(runtime,types)!: `/analytics/query` no longer echoes RLS policy field names — the declared-server-fault withhold is shared by both HTTP boundaries (#5811)
81
+
82
+ **Observable behaviour change — read this if you read, log, or assert on
83
+ `error.message` from a dispatcher-plugin route.** An error that **declares a
84
+ server fault** in the ADR-0112 envelope (`status >= 500` _and_ a non-empty
85
+ `code`) now leaves `dispatcher-plugin.errorResponseBase` with its message
86
+ replaced by `"Internal server error"`. It previously reached the caller verbatim
87
+ unless it happened to _sound_ like a SQL/driver dump. This applies to every route
88
+ that plugin mounts — `/analytics`, `/packages`, `/i18n`, `/automation`, `/auth`,
89
+ `/notifications`, `/mcp`, … — not only the one that motivated it. Nothing a
90
+ machine reads changed: the producer's `code` still arrives in the response
91
+ (`error.code`, promoted there from `details` by the shared envelope builder,
92
+ #3842), the status is untouched, and the full original text still goes to the
93
+ server log and `errorReporter` via `__obsRecordedError`.
94
+
95
+ ## What was wrong
96
+
97
+ #5367 (maintainer ruling 2026-08-06) made `read-scope-sql.ts`'s ten fail-closed
98
+ RLS lowering refusals `READ_SCOPE_COMPILE_FAILED` / 500 and taught
99
+ `POST /analytics/dataset/query` to withhold their message, because those messages
100
+ name the field names and comparands of an **administrator's** sharing rule:
101
+
102
+ ```
103
+ [read-scope-sql] unsafe field identifier "secret_policy_field" — refusing to
104
+ build read scope (fail-closed).
105
+ ```
106
+
107
+ The caller never wrote that field name and must not be able to read it out of an
108
+ error body. But the **sibling** analytics face was never closed.
109
+ `compileScopedFilterToSql` runs on both `NativeSQLStrategy.applyReadScope` and
110
+ `ObjectQLStrategy`'s echoed SQL, both of which serve `POST /analytics/query`,
111
+ which exits through `dispatcher-plugin.errorResponseBase`. That exit's only
112
+ message guard was `looksLikeInternalErrorLeak` — a heuristic over SQL/driver
113
+ _phrasing_ — and all eleven read-scope message shapes return `false` from it.
114
+ Measured at that boundary: **11 of 11 echoed verbatim**, at 500, with the policy
115
+ content in `error.message`. A real reachable disclosure, not a theoretical one.
116
+
117
+ ## What changed
118
+
119
+ - **`@objectstack/types` gains `declaresServerFault(err)`**, exported from
120
+ `error-leak.ts` beside `looksLikeInternalErrorLeak`. The heuristic asks whether
121
+ a message _sounds_ internal; the declaration asks whether the producer _said
122
+ so_. `error-leak.ts`'s own file header already states the principle — "do not
123
+ ship driver internals to clients" is a property of the HTTP boundary, not of
124
+ one router — and this is the second predicate that principle asks for.
125
+ - **Both boundaries read it.** `dispatcher-plugin.errorResponseBase` gains the
126
+ withhold (the fix); `rest-server.ts`'s `/analytics/dataset/query` catch drops
127
+ its in-line copy of the same test in favour of the shared one. #5808 wrote that
128
+ rule in-line on purpose — promoting a rule with one consumer is a speculative
129
+ surface — and this is the second consumer, so it was promoted rather than
130
+ duplicated (`#3843`/`#3867` paid for the two-implementations shape twice).
131
+ The REST face's verdict is unchanged in every case: same `status >= 500` plus
132
+ non-empty `code` test, over the same two fields.
133
+
134
+ ## What deliberately did NOT change
135
+
136
+ - ⛔ **This is not "withhold every 5xx".** #5667 kept **undeclared** 5xx errors
137
+ legible on purpose: a bare `Error` from our own code ("no strategy can handle
138
+ query …") is the operator's own bug report, names nothing tenant-sensitive, and
139
+ still falls to `looksLikeInternalErrorLeak` alone. A 5xx carrying only half an
140
+ envelope (a status with no code) is likewise still readable — inventing the
141
+ withhold for it would be the consumer-side leniency Prime Directive #12 removes.
142
+ - **4xx is untouched.** `declaresServerFault` requires `status >= 500`, so a
143
+ deliberate business/validation answer can never be swallowed by it.
144
+ - **`statusCode` is not accepted as a substitute for `status`.** `status` is the
145
+ channel ADR-0112 declares; making a disclosure rule depend on which spelling a
146
+ producer reached for would be the same leniency in a different place.
147
+ - **The heuristic was not taught to recognise `[read-scope-sql]`.** That would be
148
+ more prose sniffing — the mechanism #5352/#5367 exist to remove — and would only
149
+ ever cover the family someone remembered to add.
150
+
151
+ Coverage: `analytics-query-read-scope-withhold.test.ts` (runtime) drives six RLS
152
+ policy shapes end-to-end through a **real** `AnalyticsService` on the real
153
+ native-SQL path and the real mounted route, asserting the 500, that the whole
154
+ serialized body contains no policy detail, that `error.code` still carries
155
+ `READ_SCOPE_COMPILE_FAILED`, and that the full text is still on the
156
+ `__obsRecordedError` side-channel — plus a positive control and both sides of the
157
+ declared-vs-undeclared tiering. `error-leak.test.ts` (types) pins the predicate
158
+ directly, including that all eleven read-scope shapes stay invisible to the
159
+ heuristic. The REST face's existing `analytics-read-scope-refusal-envelope.test.ts`
160
+ is green before and after, unchanged, which is the pin on the refactor.
161
+
162
+ - 02dc076: feat(types,cli,verify)!: 只解析 host app 声明过的包 —— `NODE_PATH` 不再算数,ADR-0093 D5 那道墙从此与启动方式无关 (#4719)
163
+
164
+ **问题:契约写下了,但从没被检查过。** `@objectstack/types/node` 的
165
+ `createHostRequire` 返回一个 CJS `createRequire`,而 CJS 解析认 `NODE_PATH`
166
+ (`Module.globalPaths`)。pnpm 生成的 bin shim 第一件事就是
167
+ `export NODE_PATH=<workspace>/node_modules/.pnpm/node_modules`,于是任何被工作区里
168
+ **任意一个包**传递依赖到的包都能"从 host app 解析成功" —— 跟这个 app 声明了什么毫无关系。
169
+
170
+ 实测(cloud `apps/objectos-ee`,当时未声明 `@objectstack/organizations`):
171
+ `pnpm start`(经 shim)boot 成功、插件表里有 `Organizations`、ADR-0093 D5 一声不吭;
172
+ `node node_modules/@objectstack/cli/bin/run.js serve`(不经 shim)则
173
+ `✖ FATAL: tenancy posture 'isolated' was requested…` 并 exit 1。同一个 app、同一份
174
+ `package.json`、同一个 posture,**只因为进程是怎么被拉起来的**,走出两种结果。
175
+ 而 D5 的报错一直在教 operator "declare it in the app's package.json" —— 那正是
176
+ CLI 从来没检查过的那件事。
177
+
178
+ **改法:声明即执行。** 解析前先读 `<hostRoot>/package.json`;只有包名出现在
179
+ `dependencies` / `devDependencies` / `optionalDependencies` / `peerDependencies`
180
+ 的 **键**里,才去 host 的 `node_modules` 里查它。仅仅"能被解析到"不再算数 ——
181
+ 那正是让契约失效的那个偶然。未声明的包退回到 importing package 自身的解析
182
+ (ESM,不认 `NODE_PATH`),框架自有的包加载路径不受影响。
183
+
184
+ **两种失败从此分开报。** 今天它们都塌成同一条 `MODULE_NOT_FOUND`,补救办法却相反:
185
+
186
+ - **未声明** —— 指向"在 app 的 `package.json` 里声明并安装",并说明为什么
187
+ hoisting / `NODE_PATH` 不被接受;
188
+ - **声明了但解析不到** —— 明确说这是**安装**问题(`pnpm install`、生产 prune
189
+ 砍掉了它、dist 没构建),别再让人回去重看那份已经写对的 `package.json`。
190
+
191
+ 分类经新导出的 `hostImportFailureKind(err)` 暴露给调用方;两种错误都仍带
192
+ `code: 'MODULE_NOT_FOUND'`,`isModuleNotFoundError` 的既有判定不变。
193
+
194
+ **BREAKING — 哪类部署会从假绿变红,以及怎么修。**
195
+
196
+ 1. **靠 hoisting 苟着的部署。** 一个 app 请求了 walled tenancy posture
197
+ (`OS_TENANCY_POSTURE=group` / `isolated` 或 `OS_MULTI_ORG_ENABLED=1`)、
198
+ 却没在自己的 `package.json` 里声明 `@objectstack/organizations`,过去经 pnpm
199
+ shim 启动能正常 boot —— 现在会命中 ADR-0093 D5 并 exit 1。
200
+ **修法:在那个 app 的 `package.json` 里声明该依赖并安装。**
201
+ 这些部署本来就在未声明状态下运行,红的是一直存在的事实,不是新引入的故障:
202
+ 同一个 app 不经 shim 启动今天就已经是 exit 1。
203
+ (同样适用于 `@objectstack/service-ai` / `@objectstack/service-ai-studio`,以及
204
+ `bootStack({ multiTenant: true })`、dogfood 的 enterprise 门。)
205
+
206
+ 2. **`createHostImporter` 的签名变了**,因为它现在需要 host 的**根目录**才能读到
207
+ 那份 manifest,而一个 `NodeRequire` 无法被问出它锚在哪里:
208
+
209
+ ```diff
210
+ - createHostImporter(createHostRequire(hostRoot))
211
+ + createHostImporter(hostRoot) // 省略参数 = process.cwd(),同旧默认
212
+ ```
213
+
214
+ `createHostRequire` 本身保持不变,仍然导出。
215
+
216
+ 新增导出(`@objectstack/types/node`):`HOST_DECLARATION_FIELDS`、
217
+ `HostDeclarationField`、`HostDeclaration`、`readHostDeclaration`、
218
+ `isDeclaredByHost`、`packageNameFromSpecifier`、`HostImportFailureKind`、
219
+ `HOST_IMPORT_FAILURE_KIND`、`hostImportFailureKind`。
220
+
221
+ ### Patch Changes
222
+
223
+ - 08f93bc: fix(auth): `organization/create` gates on the authoritative `OS_TENANCY_POSTURE`, not the demoted `OS_MULTI_ORG_ENABLED` (#5233)
224
+
225
+ A deployment configured the documented way — `OS_TENANCY_POSTURE=isolated` (or
226
+ `group`), legacy boolean unset — mounted the entire organization wall and still
227
+ answered `403 Creating additional organizations is disabled on this deployment.`
228
+ to `POST /api/v1/auth/organization/create`. Org-less users had no way to create
229
+ their workspace, so the guided "Create your workspace" path was a dead end.
230
+
231
+ ADR-0105 D1 made `OS_TENANCY_POSTURE` the canonical knob and demoted
232
+ `OS_MULTI_ORG_ENABLED` to a back-compat _input_ of `resolveTenancyPosture()`.
233
+ Two sites in `AuthManager` kept reading the demoted boolean directly, so both
234
+ reported "single-org" on a deployment that had asked for a wall and got one:
235
+
236
+ - `organizationHooks.beforeCreateOrganization` — the 403 above. It now judges
237
+ `postureEnforcesWall(resolveTenancyPosture())`, matching the knob `serve.ts`'s
238
+ own ADR-0093 D5 boot guard keys on. Intent is unchanged (single-org still
239
+ refuses); only the knob is corrected.
240
+ - `/auth/config`'s `features.multiOrgEnabled` — its no-tenancy-service fallback
241
+ read the same boolean. It now falls back to the resolved posture, so a lean
242
+ embedding advertises the capability its own gate allows.
243
+
244
+ **No configuration change is needed anywhere.** Deployments that set only
245
+ `OS_MULTI_ORG_ENABLED=true` keep working unchanged — `resolveTenancyPosture()`
246
+ falls back to it — and the `OS_TENANCY_POSTURE=isolated` + `OS_MULTI_ORG_ENABLED=true`
247
+ workaround people used to unblock themselves stays valid. Deployments that set
248
+ only `OS_TENANCY_POSTURE` can now drop the redundant boolean.
249
+
250
+ `resolveMultiOrgEnabled()`'s doc comment in `@objectstack/types` — which still
251
+ instructed "the auth manager's `/auth/config` feature flag and org-create guard
252
+ … MUST call this", written before the demotion — now says the opposite: ask the
253
+ posture, and never gate on this boolean. Its behaviour is unchanged.
254
+
255
+ - Updated dependencies [9fe9c1d]
256
+ - Updated dependencies [d4e0809]
257
+ - Updated dependencies [f724f69]
258
+ - Updated dependencies [28ad90e]
259
+ - Updated dependencies [f8644c7]
260
+ - Updated dependencies [306ca50]
261
+ - Updated dependencies [978fed2]
262
+ - Updated dependencies [cfc293f]
263
+ - Updated dependencies [de70b42]
264
+ - Updated dependencies [fb3d99b]
265
+ - Updated dependencies [cdfbee2]
266
+ - Updated dependencies [29c6c9d]
267
+ - Updated dependencies [d21c001]
268
+ - Updated dependencies [f1cc3a3]
269
+ - Updated dependencies [ddc2527]
270
+ - Updated dependencies [553a47f]
271
+ - Updated dependencies [a3a884d]
272
+ - Updated dependencies [cfed092]
273
+ - Updated dependencies [2e284b2]
274
+ - Updated dependencies [1b49eaf]
275
+ - Updated dependencies [0161c7f]
276
+ - Updated dependencies [e900015]
277
+ - Updated dependencies [b5bdf48]
278
+ - Updated dependencies [a019e52]
279
+ - Updated dependencies [64fc6d5]
280
+ - Updated dependencies [947d4f9]
281
+ - Updated dependencies [eaaf03c]
282
+ - Updated dependencies [d17df80]
283
+ - Updated dependencies [7d0e7b5]
284
+ - Updated dependencies [6513c17]
285
+ - Updated dependencies [c142ced]
286
+ - Updated dependencies [eda599e]
287
+ - Updated dependencies [c001422]
288
+ - Updated dependencies [77022a9]
289
+ - Updated dependencies [52760bf]
290
+ - Updated dependencies [5543020]
291
+ - Updated dependencies [880d343]
292
+ - Updated dependencies [6e82972]
293
+ - Updated dependencies [4615a18]
294
+ - Updated dependencies [7f62706]
295
+ - Updated dependencies [667fa44]
296
+ - Updated dependencies [37e38d1]
297
+ - Updated dependencies [1eb13a0]
298
+ - Updated dependencies [c52e608]
299
+ - Updated dependencies [4dfd002]
300
+ - Updated dependencies [77be690]
301
+ - Updated dependencies [811c30c]
302
+ - Updated dependencies [b49ccfd]
303
+ - Updated dependencies [85d95e7]
304
+ - Updated dependencies [168f60f]
305
+ - Updated dependencies [244ca86]
306
+ - Updated dependencies [546ab3c]
307
+ - Updated dependencies [0b51bb6]
308
+ - Updated dependencies [d9971d3]
309
+ - Updated dependencies [abeb375]
310
+ - Updated dependencies [ef4efa8]
311
+ - Updated dependencies [cbb6a5c]
312
+ - Updated dependencies [795b6e1]
313
+ - Updated dependencies [175d789]
314
+ - Updated dependencies [55dbbba]
315
+ - Updated dependencies [72c3c86]
316
+ - Updated dependencies [7f1a635]
317
+ - Updated dependencies [502564d]
318
+ - Updated dependencies [471839d]
319
+ - Updated dependencies [b508244]
320
+ - Updated dependencies [594508e]
321
+ - Updated dependencies [1c625ca]
322
+ - Updated dependencies [71f205d]
323
+ - Updated dependencies [414395b]
324
+ - Updated dependencies [26e1029]
325
+ - Updated dependencies [108ba8d]
326
+ - Updated dependencies [b4ad984]
327
+ - Updated dependencies [a9f32df]
328
+ - Updated dependencies [aeb9b27]
329
+ - Updated dependencies [7d27da0]
330
+ - Updated dependencies [089767f]
331
+ - Updated dependencies [e4c8b6c]
332
+ - Updated dependencies [acb10f6]
333
+ - Updated dependencies [1c3da1f]
334
+ - Updated dependencies [a34fd2e]
335
+ - Updated dependencies [889ae47]
336
+ - Updated dependencies [4f4c3fb]
337
+ - Updated dependencies [7adc841]
338
+ - Updated dependencies [4845f85]
339
+ - Updated dependencies [7b005b4]
340
+ - Updated dependencies [94f7b6a]
341
+ - Updated dependencies [5c94f83]
342
+ - Updated dependencies [73e576f]
343
+ - Updated dependencies [c5a5996]
344
+ - Updated dependencies [ae490ef]
345
+ - Updated dependencies [f61c8cf]
346
+ - Updated dependencies [e3ef52b]
347
+ - Updated dependencies [07f1822]
348
+ - Updated dependencies [04fab5e]
349
+ - Updated dependencies [efedd28]
350
+ - Updated dependencies [5278e11]
351
+ - Updated dependencies [23dba62]
352
+ - Updated dependencies [ba98e26]
353
+ - Updated dependencies [fc5f536]
354
+ - Updated dependencies [f8cfbb4]
355
+ - Updated dependencies [c89d18c]
356
+ - Updated dependencies [aac90a5]
357
+ - Updated dependencies [1e6ab15]
358
+ - Updated dependencies [c87ef70]
359
+ - Updated dependencies [3cb0618]
360
+ - Updated dependencies [32a0874]
361
+ - Updated dependencies [7055c22]
362
+ - Updated dependencies [785a748]
363
+ - Updated dependencies [3af0354]
364
+ - Updated dependencies [866ff16]
365
+ - Updated dependencies [5a85e67]
366
+ - Updated dependencies [c183a12]
367
+ - Updated dependencies [8064b07]
368
+ - Updated dependencies [4a56dbd]
369
+ - Updated dependencies [06df4fa]
370
+ - @objectstack/spec@17.0.0-rc.4
371
+
3
372
  ## 17.0.0-rc.2
4
373
 
5
374
  ### Minor Changes