@objectstack/plugin-webhooks 17.2.0 → 17.4.0

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,799 @@
1
1
  # @objectstack/plugin-webhooks
2
2
 
3
+ ## 17.4.0
4
+
5
+ ### Patch Changes
6
+
7
+ - a4816a7: The three provenance-stamp `beforeUpdate` hooks stop re-reading a row the engine has already read, and their contract now states what they actually do on a multi-row update.
8
+
9
+ `sys_email_template`, `sys_sharing_rule` and `sys_webhook` each carry a hook that stamps `customized: true` when a non-system caller edits a package- or platform-seeded row — the half of seed-not-clobber that detects the admin edit. All three carried the same two comments, and both were assertions about runtime behaviour that runtime measurement falsifies:
10
+
11
+ - **"multi-row updates (no single `input.id`) are not stamped."** Not true on any engine these packages ship against. A predicate (`multi: true`) update dispatches `beforeUpdate` once per matched row, and every per-row context arrives with `input.id` bound — so the `if (!id) return` guard answered "single write" on every row of a batch and declined nothing. The rows were being stamped all along.
12
+ - **"`previous` is not resolved before beforeUpdate hooks run — read the current row ourselves."** The engine binds `previous` before dispatching `beforeUpdate` on both write shapes, so each hook was issuing its own `find` for a row the engine had just read — on a bulk edit, one extra read **per matched row**.
13
+
14
+ Observable behaviour is deliberately unchanged: the same rows are stamped, with the same values, and a bulk edit whose matched rows disagree on `managed_by` is still refused by the engine with `MULTI_UPDATE_HOOK_KEY_DIVERGENCE` (HTTP 400) rather than widening one row's stamp across the batch. What changes is the cost and the contract: the redundant per-row read is gone, and the header of each hook now describes the per-row dispatch, the single `SET` clause a predicate write shares, and why declining to stamp on a bulk edit was rejected — unstamped rows are exactly the ones the next boot's seeder overwrites.
15
+ - c5d6803: Published `.js.map` files no longer embed the complete original source text (`sourcesContent`) — comments included. `sourcemap: true` was esbuild shorthand, and esbuild's own default for `sourcesContent` is `true`; nobody had decided to publish every package's full source (including `@internal`/test-only comments) to npm inside its source maps, it fell out of a default nobody had looked at. Measured before this change: 55 of 57 publishable packages shipped embedded source text, and maps were roughly half of `@objectstack/spec`'s published bytes.
16
+
17
+ `sourcesContent: false` is now set at one shared place (`scripts/tsup-drop-sources-content.mjs`, wired into every `tsup.config.ts` via tsup's `esbuildOptions` hook — most packages build through the repo-root config directly and pick this up with no config change of their own). `mappings` are untouched, so stack-trace positions still resolve correctly to the original file/line/column; only the embedded source text is gone.
18
+
19
+ `@objectstack/cli` (built with `tsc`, not `tsup`) never embedded source text to begin with — its maps' `sources` entries point at `src/**` paths that are not part of the published tarball either way. That is not a defect unique to `cli`: every `tsup`-built package's `sources` entries are `../src/**`-relative paths that are equally outside `files: ["dist", …]`, and were merely masked by the embedded content that just stopped shipping. Shipping `src/**` in `files[]` to make `sources` resolve was rejected — it would put most of the removed bytes straight back. So `cli`'s maps are left exactly as `tsc` emits them: this is now the fleet-consistent shape (accurate `mappings`, non-resolving-but-honest `sources` labels, no embedded text), not an outlier.
20
+
21
+ A new gate, `pnpm check:sourcemap-no-sources-content`, sweeps every built, non-private package's `dist/**/*.map` and fails if any of them carries a non-empty `sourcesContent` array — so a future `tsup.config.ts` that skips the shared hook, or a toolchain upgrade that changes esbuild's default back, is caught rather than silently re-publishing source text.
22
+ - 7ceb416: Webhook fan-out now matches subscriptions on the organization dimension, closing a cross-organization delivery on walled deployments (`OS_TENANCY_POSTURE=isolated|group`).
23
+
24
+ `AutoEnqueuer` selected the subscriptions to deliver to by object name and trigger only, and every organization's `sys_webhook` rows live in one cache — so organization A's record events reached organization B's webhook endpoint, signed with B's secret, on first delivery. Both the per-record (`data.record.*`) and the bulk (`data.records.*`) fan-out paths now compare the subscription's own organization (`sys_webhook.organization_id`) with the organization the engine stamps on the event (`DataEvent.organizationId`, `BulkDataEvent.organizationId`): one equality per candidate, no lookup on the hot path.
25
+
26
+ What changes for a subscription:
27
+
28
+ - **Owned by organization A** — receives only events stamped A. An event that names no organization (an environment-wide row or an object outside the wall on the per-record path; a batch the tenant wall could not attribute to one organization on the bulk path) is not delivered inside the wall — fail-closed — and the first such refusal is logged once with the reason.
29
+ - **With no organization** (`organization_id` NULL — for example a package-declared webhook on a walled deployment) — no longer receives any organization-stamped event; the refusal is logged once per subscription. It still receives events that name no organization. On a `single`-posture deployment nothing stamps either side, so delivery there is unchanged.
30
+
31
+ An event whose `organizationId` is present but not a non-empty string is dropped loudly as off-contract, delivering to nobody.
32
+ - Updated dependencies [fe0d9a4]
33
+ - Updated dependencies [ecd2158]
34
+ - Updated dependencies [f2b5e46]
35
+ - Updated dependencies [2ed6be6]
36
+ - Updated dependencies [ed7243d]
37
+ - Updated dependencies [6ba0db4]
38
+ - Updated dependencies [625b0c3]
39
+ - Updated dependencies [233222e]
40
+ - Updated dependencies [07f40e5]
41
+ - Updated dependencies [ceb4877]
42
+ - Updated dependencies [e9fcd6b]
43
+ - Updated dependencies [90e7e6d]
44
+ - Updated dependencies [2bdabe6]
45
+ - Updated dependencies [ca326b5]
46
+ - Updated dependencies [8f404a5]
47
+ - Updated dependencies [159dbad]
48
+ - Updated dependencies [68437d4]
49
+ - Updated dependencies [abb140c]
50
+ - Updated dependencies [8333a6c]
51
+ - Updated dependencies [3e3ecb0]
52
+ - Updated dependencies [3030369]
53
+ - Updated dependencies [d5d8d50]
54
+ - Updated dependencies [e08892d]
55
+ - Updated dependencies [ae05f2e]
56
+ - Updated dependencies [b548e43]
57
+ - Updated dependencies [c463d03]
58
+ - Updated dependencies [64bd6a3]
59
+ - Updated dependencies [13c48c2]
60
+ - Updated dependencies [b0529e1]
61
+ - Updated dependencies [66dc6ab]
62
+ - Updated dependencies [6f94458]
63
+ - Updated dependencies [6e67b86]
64
+ - Updated dependencies [132742f]
65
+ - Updated dependencies [85a2459]
66
+ - Updated dependencies [50dc214]
67
+ - Updated dependencies [e89fa92]
68
+ - Updated dependencies [e9fcd6b]
69
+ - Updated dependencies [8976ea1]
70
+ - Updated dependencies [56fe8c2]
71
+ - Updated dependencies [acabd24]
72
+ - Updated dependencies [ab50c8f]
73
+ - Updated dependencies [6491463]
74
+ - Updated dependencies [89cf4d6]
75
+ - Updated dependencies [21c5dcb]
76
+ - Updated dependencies [6d4d5d3]
77
+ - Updated dependencies [ed5d557]
78
+ - Updated dependencies [bca21f7]
79
+ - Updated dependencies [e9fcd6b]
80
+ - Updated dependencies [2025b1f]
81
+ - Updated dependencies [1a7a7c9]
82
+ - Updated dependencies [e9fcd6b]
83
+ - Updated dependencies [cbca47d]
84
+ - Updated dependencies [acf4d38]
85
+ - Updated dependencies [ef3a138]
86
+ - Updated dependencies [68d5dfd]
87
+ - Updated dependencies [3e21cf0]
88
+ - Updated dependencies [4cfc93b]
89
+ - Updated dependencies [efd6b43]
90
+ - Updated dependencies [859ded3]
91
+ - Updated dependencies [fa125f3]
92
+ - Updated dependencies [74628d9]
93
+ - Updated dependencies [a646120]
94
+ - Updated dependencies [6f1ce7d]
95
+ - Updated dependencies [7778115]
96
+ - Updated dependencies [2c753fe]
97
+ - Updated dependencies [52804cd]
98
+ - Updated dependencies [3f89967]
99
+ - Updated dependencies [53cf263]
100
+ - Updated dependencies [21aabbc]
101
+ - Updated dependencies [9c270bb]
102
+ - Updated dependencies [76c8c5a]
103
+ - Updated dependencies [a84e1ce]
104
+ - Updated dependencies [bf1054a]
105
+ - Updated dependencies [d8d2776]
106
+ - Updated dependencies [222dc0f]
107
+ - Updated dependencies [e9fcd6b]
108
+ - Updated dependencies [32c917d]
109
+ - Updated dependencies [f9a3c32]
110
+ - Updated dependencies [f502898]
111
+ - Updated dependencies [51ae731]
112
+ - Updated dependencies [af7edfe]
113
+ - Updated dependencies [b60f48b]
114
+ - Updated dependencies [c78c918]
115
+ - Updated dependencies [4ca358d]
116
+ - Updated dependencies [cf9bda4]
117
+ - Updated dependencies [784cb92]
118
+ - Updated dependencies [7629f4d]
119
+ - Updated dependencies [51df9fd]
120
+ - Updated dependencies [a7da4de]
121
+ - Updated dependencies [de0bcdd]
122
+ - Updated dependencies [70f7d6d]
123
+ - Updated dependencies [c677cda]
124
+ - Updated dependencies [6acb37e]
125
+ - Updated dependencies [7797102]
126
+ - Updated dependencies [554a160]
127
+ - Updated dependencies [f7da71e]
128
+ - Updated dependencies [7f745c3]
129
+ - Updated dependencies [0a038cc]
130
+ - Updated dependencies [e9fcd6b]
131
+ - Updated dependencies [97adce2]
132
+ - Updated dependencies [a83482c]
133
+ - Updated dependencies [5eb24f8]
134
+ - Updated dependencies [2a3decc]
135
+ - Updated dependencies [cc00df2]
136
+ - Updated dependencies [cc00df2]
137
+ - Updated dependencies [f4e6adf]
138
+ - Updated dependencies [ee4a59b]
139
+ - Updated dependencies [4db3c61]
140
+ - Updated dependencies [5ca314a]
141
+ - Updated dependencies [e0af1a8]
142
+ - Updated dependencies [4771bd9]
143
+ - Updated dependencies [414c1fc]
144
+ - Updated dependencies [22c0279]
145
+ - Updated dependencies [c930f85]
146
+ - Updated dependencies [0db2947]
147
+ - Updated dependencies [92b5d7f]
148
+ - Updated dependencies [613bfbd]
149
+ - Updated dependencies [abae16a]
150
+ - Updated dependencies [094b8fd]
151
+ - Updated dependencies [c7aca0d]
152
+ - Updated dependencies [c1d8f98]
153
+ - Updated dependencies [8e0b297]
154
+ - Updated dependencies [d4f9b2a]
155
+ - Updated dependencies [5f7fa1d]
156
+ - Updated dependencies [87f0ccc]
157
+ - Updated dependencies [aedbaef]
158
+ - Updated dependencies [a727043]
159
+ - Updated dependencies [c5d6803]
160
+ - Updated dependencies [10d05bb]
161
+ - Updated dependencies [69602e5]
162
+ - Updated dependencies [c3ce76c]
163
+ - Updated dependencies [7936b29]
164
+ - Updated dependencies [46803fa]
165
+ - Updated dependencies [c2a336c]
166
+ - Updated dependencies [9f890d3]
167
+ - Updated dependencies [0bb2318]
168
+ - Updated dependencies [f7db8f4]
169
+ - Updated dependencies [1ecee3e]
170
+ - Updated dependencies [9408b7f]
171
+ - Updated dependencies [2bb0614]
172
+ - Updated dependencies [b3820c3]
173
+ - Updated dependencies [e9fcd6b]
174
+ - Updated dependencies [4df2a98]
175
+ - Updated dependencies [9bcd9be]
176
+ - Updated dependencies [b398ad2]
177
+ - Updated dependencies [99261a7]
178
+ - Updated dependencies [81b426f]
179
+ - Updated dependencies [001af1c]
180
+ - Updated dependencies [fb77aa5]
181
+ - Updated dependencies [581d8f8]
182
+ - Updated dependencies [f81afe3]
183
+ - Updated dependencies [40a44b9]
184
+ - Updated dependencies [f89812e]
185
+ - Updated dependencies [7a7fb03]
186
+ - Updated dependencies [8fd246d]
187
+ - Updated dependencies [021a735]
188
+ - Updated dependencies [7bdb163]
189
+ - @objectstack/spec@17.4.0
190
+ - @objectstack/core@17.4.0
191
+ - @objectstack/platform-objects@17.4.0
192
+ - @objectstack/service-messaging@17.4.0
193
+
194
+ ## 17.3.0
195
+
196
+ ### Patch Changes
197
+
198
+ - e7191ce: fix(build): give each `exports` condition its own `types` target in the 28 dual-build packages (#13112)
199
+
200
+ **Published-surface change, zero runtime change.** No emitted byte moves; what
201
+ moves is which declaration file a resolver READS. Maintainer ruling 2026-08-29
202
+ (decision batch #3, verbatim 「同意」) chose declaring the files over deleting
203
+ them.
204
+
205
+ ## What was wrong
206
+
207
+ These 28 packages are `"type": "module"` and dual-built, and each spelled one
208
+ `types` condition as a **sibling** of `import`/`require`:
209
+
210
+ ```json
211
+ "exports": { ".": {
212
+ "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs"
213
+ } }
214
+ ```
215
+
216
+ A sibling `types` answers for **both** conditions, so a CommonJS consumer was
217
+ handed `dist/index.d.ts` — an ES-module declaration, because the package is
218
+ `"type": "module"` — for an entry point it reaches with `require`. Measured with
219
+ `tsc --traceResolution` on a `"type": "commonjs"` fixture at `moduleResolution:
220
+ node16`:
221
+
222
+ ```
223
+ error TS1479: The current file is a CommonJS module whose imports will produce
224
+ 'require' calls; however, the referenced file is an ECMAScript module and cannot
225
+ be imported with 'require'.
226
+ ```
227
+
228
+ The JavaScript at `dist/index.cjs` loads perfectly (`check:dual-build-cjs-loads`
229
+ has asserted that for months). It is the **types** that told the consumer the
230
+ supported `require` entry point could not be required. The `dist/index.d.cts`
231
+ twin tsup emits beside it — 36 files, 5,517,701 B on this build — was named by
232
+ no condition at all and shipped in every tarball unreachable.
233
+
234
+ ## What changed
235
+
236
+ Each condition now names its own declaration, the shape TypeScript documents:
237
+
238
+ ```json
239
+ "exports": { ".": {
240
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
241
+ "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
242
+ } }
243
+ ```
244
+
245
+ 33 entry points across 27 packages, subpaths included. The root `types` field is
246
+ untouched, so `node10` resolvers are unaffected; the `import` condition resolves
247
+ exactly what it resolved before, measured as an unchanged control in the same
248
+ run.
249
+
250
+ ## `@objectstack/core` is deliberately NOT changed
251
+
252
+ Splitting a declaration in two makes TypeScript compare it nominally, and
253
+ `ObjectKernel` carries a `private plugins` member that reaches every plugin
254
+ through `PluginContext.getKernel()`. With core split, whole-repo `pnpm build`
255
+ fails in `@objectstack/verify` with 5 × TS2345 ("Types have separate
256
+ declarations of a private property 'plugins'"); with core held back and the
257
+ other 27 split, 71/71 tasks pass. So core keeps the sibling-`types` shape and
258
+ its two `.d.cts` files (220,854 B) stay unreachable, declared as such in
259
+ `check:dual-build-cjs-loads`. Splitting it needs a decision about core's public
260
+ types, not about an exports map.
261
+
262
+ ## For consumers
263
+
264
+ - **ESM consumers: nothing changes.** Same declaration file, byte for byte.
265
+ - **CJS consumers under `node16`/`nodenext`: TS1479 goes away** and the
266
+ declarations they get are the ones built for CommonJS.
267
+ - **`node10` / `moduleResolution: node` consumers: nothing changes** — they never
268
+ read `exports`.
269
+ - Nothing is removed: every path that resolved before still resolves.
270
+
271
+ Packages that are CJS-first (`require` → `./dist/index.js`, no `"type": "module"`)
272
+ were already correct and are untouched — their `dist/index.d.ts` really is the
273
+ CommonJS declaration. Their ESM mirror (an unreachable `.d.mts` under the
274
+ `import` condition) is a separate, larger population and is filed separately per
275
+ the ruling, not fixed here.
276
+
277
+ `check:dual-build-cjs-loads` grew a fourth invariant (TYPED) that reds on the old
278
+ shape, so the drift cannot return silently.
279
+ - 99d23b1: fix(service-messaging,service-automation,plugin-webhooks): stamp `organization_id` on `sys_http_delivery` rows so the cross-organization wall on `redeliver()` actually excludes other tenants' rows (#13546)
280
+
281
+ `sys_http_delivery` is tenant-scoped and `redeliver()` — the one
282
+ request-reachable door on it — deliberately scopes by the caller's
283
+ organization (#10740). But the enqueue door never stamped the
284
+ `organization_id` column, and the SQL driver's tenant term is
285
+ `(organization_id = :tenantId OR organization_id IS NULL)` — a deliberate
286
+ global-row fail-open — so 100% of delivery rows landed in the NULL arm:
287
+ visible to, and replayable by, every organization on a walled deployment.
288
+
289
+ The repair mirrors the notification outbox's existing convention
290
+ (`EnqueueDeliveryInput.organizationId`), end to end:
291
+
292
+ - `EnqueueHttpInput` gains an **optional** `organizationId` member (inherited
293
+ by `UndeliverableHttpInput`, so parked rows are tenant-stamped too), and
294
+ `HttpDelivery` surfaces it on read-back. `SqlHttpOutbox.insert` writes
295
+ `organization_id: input.organizationId ?? null` exactly like
296
+ `SqlOutbox.enqueue`; `MemoryHttpOutbox` stores the same field and — now
297
+ that its rows carry a tenant — applies `RedeliverOptions.tenantId` in
298
+ `redeliver()` with the driver's exact semantics (another organization's row
299
+ is invisible/`RESOURCE_NOT_FOUND`; an org-less row stays a global row; a
300
+ tenant-less caller stays unscoped).
301
+ - The flow `http` node (durable mode) threads its run's acting organization
302
+ (`AutomationContext.tenantId` — the same source as the `notify` node's
303
+ #11303 repair) and warns loudly when a multi-org run has none to thread.
304
+ - The webhook auto-enqueuer stamps each delivery with its subscription's own
305
+ organization (`sys_webhook.organization_id`); org-less subscriptions
306
+ enqueue org-less, unchanged.
307
+
308
+ Forward-stamping only: existing NULL rows are untouched (their disposition is
309
+ a separate decision). Producers with genuinely no organization — a
310
+ `single`-posture deployment, a stack before its first organization — keep
311
+ working unchanged; their rows land NULL, which is the honest global-row shape.
312
+ - 30928a6: fix(i18n): read the provenance companion at serving time, not only record it (#12642)
313
+
314
+ Maintainer ruling #12069 Option A (#11671) landed translation provenance as
315
+ **two** halves: `os i18n extract --source-hashes` RECORDS which source revision
316
+ a generated leaf is still a byte copy of, and `withSourceFallback` READS those
317
+ records at serving time and substitutes the current source for a leaf whose
318
+ source has moved underneath it. The recording half was then rolled out to every
319
+ bundle set. The reading half was not — measured on `main`: provenance
320
+ **recorded in 9 of 9** bundle sets and **read at serving time in 1**.
321
+
322
+ The other eight assembled their `TranslationBundle` straight from the raw
323
+ generated modules and never consulted the companion sitting beside them, so
324
+ they recorded the drift and went on serving the superseded draft. Nothing said
325
+ so: `check:i18n` compares key sets and they still matched, `check:i18n-coverage`
326
+ counts a present leaf as translated, and `check:i18n-stale-fill`'s cross-locale
327
+ rule needs a SECOND locale holding the same stale bytes before it can testify.
328
+ The measured case had one locale and no second witness.
329
+
330
+ All eight are wired here, in the shape `@objectstack/platform-objects`'s own
331
+ `metadata-translations/index.ts` uses — the committed
332
+ `<locale>.source-hashes.generated.ts` passed as the fourth argument, the third
333
+ left `undefined` because these sets have no hand-authored sections. Provenance
334
+ is now recorded in 9 of 9 sets and served in 9 of 9.
335
+
336
+ `@objectstack/plugin-webhooks` was the last of them and is the only one whose
337
+ manifest changed: `withSourceFallback` lives in `@objectstack/platform-objects`,
338
+ which that package did not declare. It was **already in that package's install
339
+ closure** through `@objectstack/service-messaging`, so the edge declares a
340
+ resolution that already resolved rather than adding a package to the graph —
341
+ and relying on it undeclared would have been a phantom dependency under this
342
+ repo's strict package manager.
343
+
344
+ `check:i18n-stale-fill` gains a second verdict, **UNSERVED PROVENANCE**, so this
345
+ cannot silently come apart again: a bundle set that commits a companion and
346
+ does not consult it at serving time now fails the build, including a tenth set
347
+ that lands tomorrow.
348
+
349
+ **Graded `patch`, and the grade is the interesting part.** No API changes, no
350
+ new exported surface, and no key set moves — substitution was chosen over
351
+ deletion precisely so key-set claims stay put (ruling #8765 Option B). What
352
+ changes is which STRING a stale leaf serves. On this tree that is **zero
353
+ leaves**: a record is only ever written for a leaf that IS a byte copy of the
354
+ current source, so the companions arrive 0-stale by construction. The change is
355
+ in what happens the next time a source string moves — the reader sees the
356
+ English source rather than a superseded draft of it, which is the same
357
+ degradation an untranslated key already produces and not a new state.
358
+ - de47336: chore(i18n): roll the generated-leaf provenance companion out to the remaining bundle sets (#12559)
359
+
360
+ `os i18n extract --source-hashes` (#11671, maintainer ruling #12069 Option A)
361
+ records, per generated translation leaf, the digest of the source revision that
362
+ leaf is **still a byte copy of** — the one signal that tells a stale fill from a
363
+ real translation once the source has moved and the two stopped being
364
+ distinguishable by value. It shipped opt-in, and exactly one of the nine i18n
365
+ bundle sets opted in. A landed detector, a changeset announcing it and a green
366
+ gate read together as *"generated translation staleness is now caught"*; for
367
+ eight of nine sets it was not, and the thing making it not caught was a single
368
+ absent flag in an extract config — invisible from all three of those surfaces.
369
+
370
+ **All eight remaining sets now opt in** — `plugin-approvals`, `plugin-audit`,
371
+ `plugin-security`, `plugin-sharing`, `plugin-webhooks`, `service-messaging`,
372
+ `service-realtime`, `service-storage`. Each documents `source-hashes` in its
373
+ extract config and commits three `<locale>.source-hashes.generated.ts`
374
+ companions, produced by the same extract run as the bundles they sit beside
375
+ (`check:i18n` compares them byte-for-byte, so they cannot be written by hand).
376
+ `check:i18n` now reports 7 bundles per set where it reported 4, and 11 for
377
+ `platform-objects` where it reported 8.
378
+
379
+ **Records count what is currently RECORDABLE, never what is covered.** A record
380
+ is written only for a leaf that *is* right now a byte copy of the current
381
+ source, so a fully translated locale starts with an empty table — which is the
382
+ instrument armed, not an instrument that measures nothing: the entry appears by
383
+ itself on the first extract after a leaf becomes a fill. Measured at this
384
+ commit, per set over its three translated locales: `service-messaging` 289,
385
+ `plugin-approvals` 61, `plugin-security` 33, `plugin-webhooks` 20,
386
+ `plugin-audit` 8, `service-storage` 7, `plugin-sharing` 1 (es-ES only; zh-CN and
387
+ ja-JP are fully translated and start empty), `service-realtime` 0 (all three
388
+ locales fully translated). **419 records written across the eight sets, 0
389
+ stale.**
390
+
391
+ **One extractor fix the rollout forced.** `--source-hashes` had one user, and
392
+ that user commits both generated sections, so the interaction with
393
+ `--no-metadata-forms` had never been exercised. The provenance table is computed
394
+ over every generated section the extractor builds; the eight sets here commit no
395
+ metadata-forms bundle, and their `metadataForms` subtree — absent from their
396
+ merge baseline — arrives as a fresh `--fill=default` copy of `en`, so every leaf
397
+ of it was recordable. First measured on `plugin-audit`: **763 records, of which
398
+ 2 were its own objects and 761 were digests of the Studio metadata-form baseline
399
+ `@objectstack/platform-objects` owns.** Those records are unreadable in the
400
+ package holding them and would have rewritten all 24 companions on any unrelated
401
+ `*.form.ts` change in `packages/spec` — the cross-package coupling ADR-0029 D8
402
+ and every `bundle-ownership.test.ts` keep out of committed bundles. The
403
+ companion now covers exactly the sections a run commits, decided by the same two
404
+ predicates that decide the bundle files. `platform-objects` commits both, so its
405
+ three committed companions are byte-for-byte unchanged.
406
+
407
+ **Grade: `patch`, and behaviour on the day it lands is unchanged for every
408
+ leaf.** A record is written only where a leaf is currently a byte copy of the
409
+ **current** source, so every record written equals the current digest and none
410
+ of them can be stale; the mechanism cannot arrive red. No committed translation
411
+ bundle changed a byte, no public API moved, and no leaf's rendered text changed.
412
+ `narrowToCommittedSections` is new but internal to `@objectstack/cli` — the
413
+ package's entrypoint does not re-export the extractor utils.
414
+
415
+ **What this does not do**, stated so the boundary is not inferred wrongly a
416
+ second time: these eight sets now *record* provenance. Reading it at serving
417
+ time is `withSourceFallback`, and that is still wired in
418
+ `@objectstack/platform-objects` alone — so a stale fill in one of the eight is
419
+ now recorded and reportable, but not yet substituted at runtime. Tracked
420
+ separately.
421
+ - 3dafd8c: Fixed the `sys_webhook` object's `ja-JP` display name (`label`) to ウェブフック, matching the already-Japanese `pluralLabel` and the bundle's own help prose (`object_name.help`, `triggers.help`), which both use the same term. Previously `label` was a stale `Webhook` fill left over from a prior source revision, so the object rendered its own name two different ways within the same locale in the Setup/admin UI. `description` (which uses "Webhook" inside a longer Japanese sentence) and the `Webhook ID` field label are unchanged — this only renames the object itself. `zh-CN` is deliberately untouched: it uses `Webhook` for both slots on purpose, as there is no established Chinese rendering of the term in this codebase.
422
+ - ad54eb3: feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)
423
+
424
+ Every plugin package now has a `tsconfig.test.json` compiled by the shared
425
+ `check:test-typecheck` gate, and its `typecheck` script names it. Before this,
426
+ the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
427
+ third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
428
+ (`plugin-security`, wired directly to `tsc` rather than to the instrument), and
429
+ 0 `check:test-typecheck` scripts.
430
+
431
+ Onboarded as a family by the director ruling of 2026-09-01 on #14062
432
+ (maintainer verbatim: 「同意」), which also carries the #5286 maintainer
433
+ authority the starting ledgers need. The smaller branch triage recommended —
434
+ declare the instrument's scope and re-site the two compile-time pins — was
435
+ recorded as considered and not taken: an instrument silent over a third of the
436
+ runtime surface is a hole readers generalise across, and that costs more than
437
+ fourteen tsconfigs.
438
+
439
+ **Measured, not assumed** (at `e80889095`, workspace closure built first). Four
440
+ packages carry residue and therefore a starting ledger — plugin-approvals 324
441
+ over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
442
+ knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
443
+ no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
444
+ any error there is red immediately with no entry to be added to — strictly
445
+ stronger than a ledger holding nothing, and the call `plugin-security` had
446
+ already recorded for itself.
447
+
448
+ ⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
449
+ ratchet able to *see* them; paydown follows the ratchet's own shrink-only
450
+ discipline on its own cards. No test file is edited here.
451
+
452
+ Two corrections to the finding's own prose, both measured: the exclusion is
453
+ narrower than "no plugin package compiles its tests" — 9 of the 14 already
454
+ compiled their tests inside the `typecheck`-invoked build config, at zero
455
+ errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
456
+ `**/*.test.ts` never excluded, so its directives were already live. The pin
457
+ this change genuinely makes real is
458
+ `plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
459
+ program had ever read.
460
+ - 598b7ec: fix(i18n): re-translate the five leaves that served a superseded source revision (#12065)
461
+
462
+ `os i18n extract` merges gaps only, so a revised source string leaves the previous
463
+ revision standing in every translated locale — in sync by key, green under
464
+ `check:i18n` and counted as translated by `check:i18n-coverage`. The five leaves
465
+ `check:i18n-stale-fill` froze in its baseline are re-translated here from the
466
+ **current** `en` source, and the baseline is ratcheted to empty in the same change.
467
+
468
+ User-visible admin/Setup help text changes in `es-ES`, `ja-JP` and `zh-CN`:
469
+
470
+ - `dataset.fields.measures.helpText` (metadata forms) — all three locales promised a
471
+ `"certified"` governance flag that was removed from the declaration in 16.0.
472
+ - `sys_webhook.fields.method.help` — all three locales served the pre-revision method
473
+ enumeration after the source became a prose description.
474
+ - `sys_webhook.pluralLabel` — `ja-JP` was an untranslated Latin fill and is now
475
+ Japanese; `zh-CN` keeps `Webhook`, which is the term this bundle's own Chinese prose
476
+ uses and which carries no plural inflection.
477
+ - `sys_http_delivery.fields.attempts.help` — `es-ES` / `ja-JP` held an English fill and
478
+ `zh-CN` a translation of the same superseded source; all three now carry the
479
+ PARKED / terminal-row clause the source documents.
480
+ - `sys_notification_subscription.fields.principal.help` — the selector list was missing
481
+ the `owner_of:object:id` and bare-email forms in all three locales.
482
+
483
+ No schema, export or runtime behaviour changes: translated-locale leaf values only,
484
+ plus the shrink-only ratchet baseline.
485
+ - Updated dependencies [809d417]
486
+ - Updated dependencies [387e231]
487
+ - Updated dependencies [f794e4e]
488
+ - Updated dependencies [cae2169]
489
+ - Updated dependencies [b812a54]
490
+ - Updated dependencies [2d4fa75]
491
+ - Updated dependencies [0e4e51b]
492
+ - Updated dependencies [e84bbf6]
493
+ - Updated dependencies [effae80]
494
+ - Updated dependencies [efb3513]
495
+ - Updated dependencies [d62f990]
496
+ - Updated dependencies [c45d8e6]
497
+ - Updated dependencies [2e3e8c7]
498
+ - Updated dependencies [e621291]
499
+ - Updated dependencies [655b106]
500
+ - Updated dependencies [40a93b5]
501
+ - Updated dependencies [d5b330d]
502
+ - Updated dependencies [dda969c]
503
+ - Updated dependencies [1f45690]
504
+ - Updated dependencies [277948f]
505
+ - Updated dependencies [8bdd955]
506
+ - Updated dependencies [f3bbbef]
507
+ - Updated dependencies [4f24e9d]
508
+ - Updated dependencies [e27583e]
509
+ - Updated dependencies [4bd6faa]
510
+ - Updated dependencies [86cbe37]
511
+ - Updated dependencies [6a180e4]
512
+ - Updated dependencies [474242f]
513
+ - Updated dependencies [63cd487]
514
+ - Updated dependencies [bd4aa4e]
515
+ - Updated dependencies [803eaab]
516
+ - Updated dependencies [f8e8f03]
517
+ - Updated dependencies [983edf1]
518
+ - Updated dependencies [eae824e]
519
+ - Updated dependencies [f6fa22c]
520
+ - Updated dependencies [8a483b3]
521
+ - Updated dependencies [3bc2e38]
522
+ - Updated dependencies [97bcd99]
523
+ - Updated dependencies [df59de0]
524
+ - Updated dependencies [96e25a8]
525
+ - Updated dependencies [f75a38a]
526
+ - Updated dependencies [7a25e7d]
527
+ - Updated dependencies [1fa05a6]
528
+ - Updated dependencies [c85a265]
529
+ - Updated dependencies [dcb10a5]
530
+ - Updated dependencies [773a999]
531
+ - Updated dependencies [35dffea]
532
+ - Updated dependencies [d8024f0]
533
+ - Updated dependencies [8120808]
534
+ - Updated dependencies [776a098]
535
+ - Updated dependencies [5060877]
536
+ - Updated dependencies [4f6325d]
537
+ - Updated dependencies [52954c0]
538
+ - Updated dependencies [2aa8456]
539
+ - Updated dependencies [93809a3]
540
+ - Updated dependencies [7c0d0c3]
541
+ - Updated dependencies [daae7aa]
542
+ - Updated dependencies [8dc22d6]
543
+ - Updated dependencies [a392dbf]
544
+ - Updated dependencies [279431e]
545
+ - Updated dependencies [948dd6b]
546
+ - Updated dependencies [3b4c56c]
547
+ - Updated dependencies [ae8edd2]
548
+ - Updated dependencies [e25403c]
549
+ - Updated dependencies [64baa68]
550
+ - Updated dependencies [9fa70d7]
551
+ - Updated dependencies [09db64a]
552
+ - Updated dependencies [92916e7]
553
+ - Updated dependencies [a84f3ea]
554
+ - Updated dependencies [f2eaae8]
555
+ - Updated dependencies [c09451b]
556
+ - Updated dependencies [ba64877]
557
+ - Updated dependencies [e7191ce]
558
+ - Updated dependencies [7345308]
559
+ - Updated dependencies [79b6a22]
560
+ - Updated dependencies [30d96ab]
561
+ - Updated dependencies [f658793]
562
+ - Updated dependencies [c95ad19]
563
+ - Updated dependencies [e58ea8b]
564
+ - Updated dependencies [4a17645]
565
+ - Updated dependencies [3795c5f]
566
+ - Updated dependencies [8ab926b]
567
+ - Updated dependencies [7317cf2]
568
+ - Updated dependencies [e25e839]
569
+ - Updated dependencies [5997207]
570
+ - Updated dependencies [8b13cc8]
571
+ - Updated dependencies [4a4a35d]
572
+ - Updated dependencies [86e765a]
573
+ - Updated dependencies [1d7e76a]
574
+ - Updated dependencies [53dc739]
575
+ - Updated dependencies [fd289be]
576
+ - Updated dependencies [03bf7b1]
577
+ - Updated dependencies [f90e820]
578
+ - Updated dependencies [18d816a]
579
+ - Updated dependencies [e8bd715]
580
+ - Updated dependencies [b91c351]
581
+ - Updated dependencies [a28a3c0]
582
+ - Updated dependencies [daeaaf9]
583
+ - Updated dependencies [c459da6]
584
+ - Updated dependencies [e914733]
585
+ - Updated dependencies [f887e52]
586
+ - Updated dependencies [881f8d8]
587
+ - Updated dependencies [3bfa1e6]
588
+ - Updated dependencies [0a8ebf3]
589
+ - Updated dependencies [901355c]
590
+ - Updated dependencies [34ce8e7]
591
+ - Updated dependencies [33681ea]
592
+ - Updated dependencies [4635f3e]
593
+ - Updated dependencies [fd289be]
594
+ - Updated dependencies [ee3595c]
595
+ - Updated dependencies [99d23b1]
596
+ - Updated dependencies [09b4f4e]
597
+ - Updated dependencies [30928a6]
598
+ - Updated dependencies [de47336]
599
+ - Updated dependencies [b2eab95]
600
+ - Updated dependencies [93940d4]
601
+ - Updated dependencies [3a04b01]
602
+ - Updated dependencies [45b9051]
603
+ - Updated dependencies [3954fb7]
604
+ - Updated dependencies [4805b56]
605
+ - Updated dependencies [b9e9227]
606
+ - Updated dependencies [d395692]
607
+ - Updated dependencies [5894d30]
608
+ - Updated dependencies [a3765f6]
609
+ - Updated dependencies [2d5cee3]
610
+ - Updated dependencies [e22158f]
611
+ - Updated dependencies [7404925]
612
+ - Updated dependencies [0c2334f]
613
+ - Updated dependencies [778c59f]
614
+ - Updated dependencies [d2619fd]
615
+ - Updated dependencies [af56546]
616
+ - Updated dependencies [6acb11a]
617
+ - Updated dependencies [33c5fd3]
618
+ - Updated dependencies [20b0fdb]
619
+ - Updated dependencies [905019b]
620
+ - Updated dependencies [a286411]
621
+ - Updated dependencies [98c0d33]
622
+ - Updated dependencies [368a82e]
623
+ - Updated dependencies [a3d5724]
624
+ - Updated dependencies [93ea19b]
625
+ - Updated dependencies [9ee2dcf]
626
+ - Updated dependencies [8cb96ec]
627
+ - Updated dependencies [8f10a79]
628
+ - Updated dependencies [6269a55]
629
+ - Updated dependencies [a17da05]
630
+ - Updated dependencies [a8c00e2]
631
+ - Updated dependencies [0fb8760]
632
+ - Updated dependencies [e5ce2ed]
633
+ - Updated dependencies [be21955]
634
+ - Updated dependencies [bc56e18]
635
+ - Updated dependencies [be21955]
636
+ - Updated dependencies [a9ee989]
637
+ - Updated dependencies [4d0d944]
638
+ - Updated dependencies [15d58db]
639
+ - Updated dependencies [d63b014]
640
+ - Updated dependencies [9abe4e4]
641
+ - Updated dependencies [2cc7122]
642
+ - Updated dependencies [b6d9432]
643
+ - Updated dependencies [3b5f036]
644
+ - Updated dependencies [50d6c92]
645
+ - Updated dependencies [9e0ba21]
646
+ - Updated dependencies [311433f]
647
+ - Updated dependencies [3e5ad08]
648
+ - Updated dependencies [9abe4e4]
649
+ - Updated dependencies [b7131f3]
650
+ - Updated dependencies [e5812fa]
651
+ - Updated dependencies [7085f90]
652
+ - Updated dependencies [dee4dd4]
653
+ - Updated dependencies [ce7e497]
654
+ - Updated dependencies [51ecb2f]
655
+ - Updated dependencies [9086761]
656
+ - Updated dependencies [f6344e7]
657
+ - Updated dependencies [42a117b]
658
+ - Updated dependencies [e4902d2]
659
+ - Updated dependencies [1401ae7]
660
+ - Updated dependencies [e577445]
661
+ - Updated dependencies [4297fe7]
662
+ - Updated dependencies [e398863]
663
+ - Updated dependencies [d16df74]
664
+ - Updated dependencies [d79c602]
665
+ - Updated dependencies [f11fc61]
666
+ - Updated dependencies [e808890]
667
+ - Updated dependencies [8f79379]
668
+ - Updated dependencies [e6ca40e]
669
+ - Updated dependencies [0c77ea4]
670
+ - Updated dependencies [52954c0]
671
+ - Updated dependencies [89eb997]
672
+ - Updated dependencies [7131f12]
673
+ - Updated dependencies [aa5994e]
674
+ - Updated dependencies [be93457]
675
+ - Updated dependencies [a65db76]
676
+ - Updated dependencies [15eb2c9]
677
+ - Updated dependencies [5691b07]
678
+ - Updated dependencies [d9cf78e]
679
+ - Updated dependencies [1a47a53]
680
+ - Updated dependencies [2a6122b]
681
+ - Updated dependencies [225e769]
682
+ - Updated dependencies [8af88dd]
683
+ - Updated dependencies [fb5fbb8]
684
+ - Updated dependencies [d7b3963]
685
+ - Updated dependencies [33184fd]
686
+ - Updated dependencies [7c41693]
687
+ - Updated dependencies [b72db01]
688
+ - Updated dependencies [dce5cd4]
689
+ - Updated dependencies [9688f58]
690
+ - Updated dependencies [556ebc1]
691
+ - Updated dependencies [177ebdc]
692
+ - Updated dependencies [8d237b4]
693
+ - Updated dependencies [2d2e6f0]
694
+ - Updated dependencies [2d8dd8d]
695
+ - Updated dependencies [22d573e]
696
+ - Updated dependencies [b5a2398]
697
+ - Updated dependencies [348860c]
698
+ - Updated dependencies [5383fa6]
699
+ - Updated dependencies [5b3ff63]
700
+ - Updated dependencies [1a6a19c]
701
+ - Updated dependencies [064d484]
702
+ - Updated dependencies [527e050]
703
+ - Updated dependencies [dd33bf9]
704
+ - Updated dependencies [4cb2a90]
705
+ - Updated dependencies [74a7804]
706
+ - Updated dependencies [53d3689]
707
+ - Updated dependencies [b3a63d3]
708
+ - Updated dependencies [49f0dcf]
709
+ - Updated dependencies [033a34c]
710
+ - Updated dependencies [4d25d22]
711
+ - Updated dependencies [1ffee51]
712
+ - Updated dependencies [5ae4303]
713
+ - Updated dependencies [ece4dad]
714
+ - Updated dependencies [e9b377e]
715
+ - Updated dependencies [146f448]
716
+ - Updated dependencies [735f5c7]
717
+ - Updated dependencies [a7e18de]
718
+ - Updated dependencies [366f895]
719
+ - Updated dependencies [dc75ba8]
720
+ - Updated dependencies [cce0aa9]
721
+ - Updated dependencies [e764507]
722
+ - Updated dependencies [cff17af]
723
+ - Updated dependencies [39404f3]
724
+ - Updated dependencies [ca1965f]
725
+ - Updated dependencies [8619f95]
726
+ - Updated dependencies [b706af9]
727
+ - Updated dependencies [add4360]
728
+ - Updated dependencies [e0abc38]
729
+ - Updated dependencies [fc9ba76]
730
+ - Updated dependencies [0f94cc7]
731
+ - Updated dependencies [a11c1a5]
732
+ - Updated dependencies [71f9cd1]
733
+ - Updated dependencies [ee17d86]
734
+ - Updated dependencies [cdbd920]
735
+ - Updated dependencies [18c432e]
736
+ - Updated dependencies [3c418c4]
737
+ - Updated dependencies [fa8715a]
738
+ - Updated dependencies [a933ed7]
739
+ - Updated dependencies [b3ca463]
740
+ - Updated dependencies [a933ed7]
741
+ - Updated dependencies [0d4a6a8]
742
+ - Updated dependencies [518d5e5]
743
+ - Updated dependencies [6643ba1]
744
+ - Updated dependencies [eeba2ef]
745
+ - Updated dependencies [ec4c4d2]
746
+ - Updated dependencies [424f73c]
747
+ - Updated dependencies [cccbe51]
748
+ - Updated dependencies [a8d6b1d]
749
+ - Updated dependencies [e4a7695]
750
+ - Updated dependencies [87075b1]
751
+ - Updated dependencies [fc58a99]
752
+ - Updated dependencies [14cfc00]
753
+ - Updated dependencies [1c6f7b4]
754
+ - Updated dependencies [e854a53]
755
+ - Updated dependencies [dfebfc8]
756
+ - Updated dependencies [598b7ec]
757
+ - Updated dependencies [ffbb7a1]
758
+ - Updated dependencies [d028b37]
759
+ - Updated dependencies [f7b25c5]
760
+ - Updated dependencies [122ef38]
761
+ - Updated dependencies [4a37870]
762
+ - Updated dependencies [428f9b2]
763
+ - Updated dependencies [aa7ff56]
764
+ - Updated dependencies [811a3c2]
765
+ - Updated dependencies [1401ae7]
766
+ - Updated dependencies [2fd3f1c]
767
+ - Updated dependencies [c41b42e]
768
+ - Updated dependencies [c4db311]
769
+ - Updated dependencies [750fff5]
770
+ - Updated dependencies [c19035e]
771
+ - Updated dependencies [ececf7a]
772
+ - Updated dependencies [d173125]
773
+ - Updated dependencies [8eeca27]
774
+ - Updated dependencies [8425c17]
775
+ - Updated dependencies [a5ef1d8]
776
+ - Updated dependencies [772d5de]
777
+ - Updated dependencies [ce80ec2]
778
+ - Updated dependencies [b372318]
779
+ - Updated dependencies [97a2263]
780
+ - Updated dependencies [29d0676]
781
+ - Updated dependencies [0169d49]
782
+ - Updated dependencies [6bd3231]
783
+ - Updated dependencies [d2b5ba8]
784
+ - Updated dependencies [b799ac5]
785
+ - Updated dependencies [8f74307]
786
+ - Updated dependencies [d23dc08]
787
+ - Updated dependencies [644ad50]
788
+ - Updated dependencies [0da7cd2]
789
+ - Updated dependencies [28a5c3e]
790
+ - Updated dependencies [4bc18e5]
791
+ - Updated dependencies [9f57f1e]
792
+ - @objectstack/spec@17.3.0
793
+ - @objectstack/platform-objects@17.3.0
794
+ - @objectstack/core@17.3.0
795
+ - @objectstack/service-messaging@17.3.0
796
+
3
797
  ## 17.2.0
4
798
 
5
799
  ### Minor Changes