@objectstack/plugin-reports 17.1.0 → 17.3.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,477 @@
1
1
  # @objectstack/plugin-reports
2
2
 
3
+ ## 17.3.0
4
+
5
+ ### Patch Changes
6
+
7
+ - ad54eb3: feat(tooling): onboard all 14 `packages/plugins/**` packages into `check:test-typecheck` (#14062)
8
+
9
+ Every plugin package now has a `tsconfig.test.json` compiled by the shared
10
+ `check:test-typecheck` gate, and its `typecheck` script names it. Before this,
11
+ the shrink-only `test-typecheck-debt.json` ratchet said **nothing** about a
12
+ third of the repo's runtime surface: 14 packages, 1 `tsconfig.test.json`
13
+ (`plugin-security`, wired directly to `tsc` rather than to the instrument), and
14
+ 0 `check:test-typecheck` scripts.
15
+
16
+ Onboarded as a family by the director ruling of 2026-09-01 on #14062
17
+ (maintainer verbatim: 「同意」), which also carries the #5286 maintainer
18
+ authority the starting ledgers need. The smaller branch triage recommended —
19
+ declare the instrument's scope and re-site the two compile-time pins — was
20
+ recorded as considered and not taken: an instrument silent over a third of the
21
+ runtime surface is a hole readers generalise across, and that costs more than
22
+ fourteen tsconfigs.
23
+
24
+ **Measured, not assumed** (at `e80889095`, workspace closure built first). Four
25
+ packages carry residue and therefore a starting ledger — plugin-approvals 324
26
+ over 8 files, plugin-auth 94 over 10, plugin-sharing 3 over 2,
27
+ knowledge-ragflow 3 over 1. The other ten measure **zero** and deliberately get
28
+ no ledger file at all: the gate reads a missing ledger as `{ entries: {} }`, so
29
+ any error there is red immediately with no entry to be added to — strictly
30
+ stronger than a ledger holding nothing, and the call `plugin-security` had
31
+ already recorded for itself.
32
+
33
+ ⛔ **This does not repair 345 type errors.** Per ruling item 3 it makes the
34
+ ratchet able to *see* them; paydown follows the ratchet's own shrink-only
35
+ discipline on its own cards. No test file is edited here.
36
+
37
+ Two corrections to the finding's own prose, both measured: the exclusion is
38
+ narrower than "no plugin package compiles its tests" — 9 of the 14 already
39
+ compiled their tests inside the `typecheck`-invoked build config, at zero
40
+ errors — and `exec-context-annotation.pin.ts` is a `.pin.ts`, which
41
+ `**/*.test.ts` never excluded, so its directives were already live. The pin
42
+ this change genuinely makes real is
43
+ `plugin-approvals/src/manager-org-screen-parity.contract.test.ts`, which no tsc
44
+ program had ever read.
45
+ - a1c804b: Report CSV and HTML exports now infer their columns from **every** row of the result set, not from the first 50. Column inference sampled `rows.slice(0, 50)` while the projection it produced was applied to all rows, so when a report declared no explicit `query.fields`, any key whose first occurrence fell at row 51 or later was absent from the header *and* dropped from every row that carried it. The export gave no signal: the CSV was well-formed, every row had the same arity, and nothing marked a column as inferred rather than declared, so a recipient of a scheduled report attachment could not tell. Sparse columns are the normal shape of report output — an optional field, a formula only some records satisfy, a lookup that resolves for a subset — and the sampled prefix is the query's first page in its own `orderBy`, so for a report sorted by status or created date the sample correlated with exactly the column it dropped. Both affected renderers are fixed (`csv`, which is also the `default:` format branch, and `html_table`); `json` was never affected. Already-inferred columns keep their position and late-appearing ones are appended, so an export that was correct before is byte-identical now.
46
+ - Updated dependencies [809d417]
47
+ - Updated dependencies [387e231]
48
+ - Updated dependencies [f794e4e]
49
+ - Updated dependencies [cae2169]
50
+ - Updated dependencies [b812a54]
51
+ - Updated dependencies [2d4fa75]
52
+ - Updated dependencies [0e4e51b]
53
+ - Updated dependencies [e84bbf6]
54
+ - Updated dependencies [effae80]
55
+ - Updated dependencies [efb3513]
56
+ - Updated dependencies [d62f990]
57
+ - Updated dependencies [c45d8e6]
58
+ - Updated dependencies [2e3e8c7]
59
+ - Updated dependencies [e621291]
60
+ - Updated dependencies [655b106]
61
+ - Updated dependencies [40a93b5]
62
+ - Updated dependencies [d5b330d]
63
+ - Updated dependencies [dda969c]
64
+ - Updated dependencies [1f45690]
65
+ - Updated dependencies [277948f]
66
+ - Updated dependencies [8bdd955]
67
+ - Updated dependencies [f3bbbef]
68
+ - Updated dependencies [4f24e9d]
69
+ - Updated dependencies [e27583e]
70
+ - Updated dependencies [4bd6faa]
71
+ - Updated dependencies [86cbe37]
72
+ - Updated dependencies [6a180e4]
73
+ - Updated dependencies [474242f]
74
+ - Updated dependencies [63cd487]
75
+ - Updated dependencies [bd4aa4e]
76
+ - Updated dependencies [803eaab]
77
+ - Updated dependencies [f8e8f03]
78
+ - Updated dependencies [983edf1]
79
+ - Updated dependencies [eae824e]
80
+ - Updated dependencies [f6fa22c]
81
+ - Updated dependencies [8a483b3]
82
+ - Updated dependencies [3bc2e38]
83
+ - Updated dependencies [97bcd99]
84
+ - Updated dependencies [df59de0]
85
+ - Updated dependencies [96e25a8]
86
+ - Updated dependencies [f75a38a]
87
+ - Updated dependencies [7a25e7d]
88
+ - Updated dependencies [1fa05a6]
89
+ - Updated dependencies [c85a265]
90
+ - Updated dependencies [dcb10a5]
91
+ - Updated dependencies [773a999]
92
+ - Updated dependencies [35dffea]
93
+ - Updated dependencies [d8024f0]
94
+ - Updated dependencies [8120808]
95
+ - Updated dependencies [776a098]
96
+ - Updated dependencies [5060877]
97
+ - Updated dependencies [4f6325d]
98
+ - Updated dependencies [52954c0]
99
+ - Updated dependencies [2aa8456]
100
+ - Updated dependencies [93809a3]
101
+ - Updated dependencies [7c0d0c3]
102
+ - Updated dependencies [daae7aa]
103
+ - Updated dependencies [8dc22d6]
104
+ - Updated dependencies [a392dbf]
105
+ - Updated dependencies [279431e]
106
+ - Updated dependencies [948dd6b]
107
+ - Updated dependencies [3b4c56c]
108
+ - Updated dependencies [ae8edd2]
109
+ - Updated dependencies [e25403c]
110
+ - Updated dependencies [64baa68]
111
+ - Updated dependencies [9fa70d7]
112
+ - Updated dependencies [09db64a]
113
+ - Updated dependencies [92916e7]
114
+ - Updated dependencies [a84f3ea]
115
+ - Updated dependencies [f2eaae8]
116
+ - Updated dependencies [c09451b]
117
+ - Updated dependencies [ba64877]
118
+ - Updated dependencies [7345308]
119
+ - Updated dependencies [79b6a22]
120
+ - Updated dependencies [30d96ab]
121
+ - Updated dependencies [f658793]
122
+ - Updated dependencies [c95ad19]
123
+ - Updated dependencies [e58ea8b]
124
+ - Updated dependencies [4a17645]
125
+ - Updated dependencies [3795c5f]
126
+ - Updated dependencies [8ab926b]
127
+ - Updated dependencies [7317cf2]
128
+ - Updated dependencies [e25e839]
129
+ - Updated dependencies [5997207]
130
+ - Updated dependencies [8b13cc8]
131
+ - Updated dependencies [4a4a35d]
132
+ - Updated dependencies [86e765a]
133
+ - Updated dependencies [1d7e76a]
134
+ - Updated dependencies [53dc739]
135
+ - Updated dependencies [fd289be]
136
+ - Updated dependencies [03bf7b1]
137
+ - Updated dependencies [f90e820]
138
+ - Updated dependencies [18d816a]
139
+ - Updated dependencies [e8bd715]
140
+ - Updated dependencies [b91c351]
141
+ - Updated dependencies [a28a3c0]
142
+ - Updated dependencies [daeaaf9]
143
+ - Updated dependencies [c459da6]
144
+ - Updated dependencies [e914733]
145
+ - Updated dependencies [f887e52]
146
+ - Updated dependencies [881f8d8]
147
+ - Updated dependencies [3bfa1e6]
148
+ - Updated dependencies [0a8ebf3]
149
+ - Updated dependencies [901355c]
150
+ - Updated dependencies [34ce8e7]
151
+ - Updated dependencies [33681ea]
152
+ - Updated dependencies [4635f3e]
153
+ - Updated dependencies [fd289be]
154
+ - Updated dependencies [ee3595c]
155
+ - Updated dependencies [09b4f4e]
156
+ - Updated dependencies [b2eab95]
157
+ - Updated dependencies [93940d4]
158
+ - Updated dependencies [3a04b01]
159
+ - Updated dependencies [45b9051]
160
+ - Updated dependencies [3954fb7]
161
+ - Updated dependencies [4805b56]
162
+ - Updated dependencies [b9e9227]
163
+ - Updated dependencies [d395692]
164
+ - Updated dependencies [5894d30]
165
+ - Updated dependencies [a3765f6]
166
+ - Updated dependencies [2d5cee3]
167
+ - Updated dependencies [e22158f]
168
+ - Updated dependencies [7404925]
169
+ - Updated dependencies [0c2334f]
170
+ - Updated dependencies [778c59f]
171
+ - Updated dependencies [d2619fd]
172
+ - Updated dependencies [af56546]
173
+ - Updated dependencies [6acb11a]
174
+ - Updated dependencies [33c5fd3]
175
+ - Updated dependencies [20b0fdb]
176
+ - Updated dependencies [905019b]
177
+ - Updated dependencies [a286411]
178
+ - Updated dependencies [98c0d33]
179
+ - Updated dependencies [368a82e]
180
+ - Updated dependencies [a3d5724]
181
+ - Updated dependencies [93ea19b]
182
+ - Updated dependencies [9ee2dcf]
183
+ - Updated dependencies [8cb96ec]
184
+ - Updated dependencies [8f10a79]
185
+ - Updated dependencies [6269a55]
186
+ - Updated dependencies [a17da05]
187
+ - Updated dependencies [a8c00e2]
188
+ - Updated dependencies [0fb8760]
189
+ - Updated dependencies [e5ce2ed]
190
+ - Updated dependencies [be21955]
191
+ - Updated dependencies [bc56e18]
192
+ - Updated dependencies [be21955]
193
+ - Updated dependencies [a9ee989]
194
+ - Updated dependencies [4d0d944]
195
+ - Updated dependencies [15d58db]
196
+ - Updated dependencies [d63b014]
197
+ - Updated dependencies [9abe4e4]
198
+ - Updated dependencies [2cc7122]
199
+ - Updated dependencies [50d6c92]
200
+ - Updated dependencies [9e0ba21]
201
+ - Updated dependencies [311433f]
202
+ - Updated dependencies [3e5ad08]
203
+ - Updated dependencies [9abe4e4]
204
+ - Updated dependencies [b7131f3]
205
+ - Updated dependencies [e5812fa]
206
+ - Updated dependencies [7085f90]
207
+ - Updated dependencies [dee4dd4]
208
+ - Updated dependencies [ce7e497]
209
+ - Updated dependencies [51ecb2f]
210
+ - Updated dependencies [9086761]
211
+ - Updated dependencies [f6344e7]
212
+ - Updated dependencies [42a117b]
213
+ - Updated dependencies [1401ae7]
214
+ - Updated dependencies [4297fe7]
215
+ - Updated dependencies [e398863]
216
+ - Updated dependencies [d16df74]
217
+ - Updated dependencies [d79c602]
218
+ - Updated dependencies [f11fc61]
219
+ - Updated dependencies [e808890]
220
+ - Updated dependencies [8f79379]
221
+ - Updated dependencies [e6ca40e]
222
+ - Updated dependencies [0c77ea4]
223
+ - Updated dependencies [52954c0]
224
+ - Updated dependencies [89eb997]
225
+ - Updated dependencies [7131f12]
226
+ - Updated dependencies [aa5994e]
227
+ - Updated dependencies [be93457]
228
+ - Updated dependencies [a65db76]
229
+ - Updated dependencies [15eb2c9]
230
+ - Updated dependencies [5691b07]
231
+ - Updated dependencies [2a6122b]
232
+ - Updated dependencies [225e769]
233
+ - Updated dependencies [8af88dd]
234
+ - Updated dependencies [fb5fbb8]
235
+ - Updated dependencies [d7b3963]
236
+ - Updated dependencies [33184fd]
237
+ - Updated dependencies [7c41693]
238
+ - Updated dependencies [b72db01]
239
+ - Updated dependencies [dce5cd4]
240
+ - Updated dependencies [9688f58]
241
+ - Updated dependencies [556ebc1]
242
+ - Updated dependencies [177ebdc]
243
+ - Updated dependencies [8d237b4]
244
+ - Updated dependencies [2d2e6f0]
245
+ - Updated dependencies [2d8dd8d]
246
+ - Updated dependencies [22d573e]
247
+ - Updated dependencies [b5a2398]
248
+ - Updated dependencies [348860c]
249
+ - Updated dependencies [5383fa6]
250
+ - Updated dependencies [5b3ff63]
251
+ - Updated dependencies [1a6a19c]
252
+ - Updated dependencies [064d484]
253
+ - Updated dependencies [527e050]
254
+ - Updated dependencies [dd33bf9]
255
+ - Updated dependencies [4cb2a90]
256
+ - Updated dependencies [74a7804]
257
+ - Updated dependencies [53d3689]
258
+ - Updated dependencies [b3a63d3]
259
+ - Updated dependencies [49f0dcf]
260
+ - Updated dependencies [033a34c]
261
+ - Updated dependencies [4d25d22]
262
+ - Updated dependencies [1ffee51]
263
+ - Updated dependencies [5ae4303]
264
+ - Updated dependencies [ece4dad]
265
+ - Updated dependencies [e9b377e]
266
+ - Updated dependencies [146f448]
267
+ - Updated dependencies [735f5c7]
268
+ - Updated dependencies [a7e18de]
269
+ - Updated dependencies [366f895]
270
+ - Updated dependencies [dc75ba8]
271
+ - Updated dependencies [cce0aa9]
272
+ - Updated dependencies [e764507]
273
+ - Updated dependencies [cff17af]
274
+ - Updated dependencies [39404f3]
275
+ - Updated dependencies [ca1965f]
276
+ - Updated dependencies [8619f95]
277
+ - Updated dependencies [b706af9]
278
+ - Updated dependencies [add4360]
279
+ - Updated dependencies [e0abc38]
280
+ - Updated dependencies [fc9ba76]
281
+ - Updated dependencies [0f94cc7]
282
+ - Updated dependencies [a11c1a5]
283
+ - Updated dependencies [71f9cd1]
284
+ - Updated dependencies [ee17d86]
285
+ - Updated dependencies [cdbd920]
286
+ - Updated dependencies [18c432e]
287
+ - Updated dependencies [3c418c4]
288
+ - Updated dependencies [fa8715a]
289
+ - Updated dependencies [a933ed7]
290
+ - Updated dependencies [b3ca463]
291
+ - Updated dependencies [a933ed7]
292
+ - Updated dependencies [0d4a6a8]
293
+ - Updated dependencies [518d5e5]
294
+ - Updated dependencies [6643ba1]
295
+ - Updated dependencies [eeba2ef]
296
+ - Updated dependencies [ec4c4d2]
297
+ - Updated dependencies [424f73c]
298
+ - Updated dependencies [cccbe51]
299
+ - Updated dependencies [a8d6b1d]
300
+ - Updated dependencies [e4a7695]
301
+ - Updated dependencies [87075b1]
302
+ - Updated dependencies [fc58a99]
303
+ - Updated dependencies [14cfc00]
304
+ - Updated dependencies [1c6f7b4]
305
+ - Updated dependencies [e854a53]
306
+ - Updated dependencies [dfebfc8]
307
+ - Updated dependencies [598b7ec]
308
+ - Updated dependencies [d028b37]
309
+ - Updated dependencies [f7b25c5]
310
+ - Updated dependencies [122ef38]
311
+ - Updated dependencies [4a37870]
312
+ - Updated dependencies [428f9b2]
313
+ - Updated dependencies [aa7ff56]
314
+ - Updated dependencies [811a3c2]
315
+ - Updated dependencies [1401ae7]
316
+ - Updated dependencies [2fd3f1c]
317
+ - Updated dependencies [c41b42e]
318
+ - Updated dependencies [c4db311]
319
+ - Updated dependencies [750fff5]
320
+ - Updated dependencies [c19035e]
321
+ - Updated dependencies [ececf7a]
322
+ - Updated dependencies [d173125]
323
+ - Updated dependencies [8eeca27]
324
+ - Updated dependencies [8425c17]
325
+ - Updated dependencies [a5ef1d8]
326
+ - Updated dependencies [772d5de]
327
+ - Updated dependencies [ce80ec2]
328
+ - Updated dependencies [b372318]
329
+ - Updated dependencies [97a2263]
330
+ - Updated dependencies [29d0676]
331
+ - Updated dependencies [0169d49]
332
+ - Updated dependencies [6bd3231]
333
+ - Updated dependencies [d2b5ba8]
334
+ - Updated dependencies [b799ac5]
335
+ - Updated dependencies [8f74307]
336
+ - Updated dependencies [d23dc08]
337
+ - Updated dependencies [644ad50]
338
+ - Updated dependencies [0da7cd2]
339
+ - Updated dependencies [28a5c3e]
340
+ - Updated dependencies [4bc18e5]
341
+ - Updated dependencies [9f57f1e]
342
+ - @objectstack/spec@17.3.0
343
+ - @objectstack/platform-objects@17.3.0
344
+ - @objectstack/core@17.3.0
345
+
346
+ ## 17.2.0
347
+
348
+ ### Minor Changes
349
+
350
+ - e222a53: **BREAKING** (compile-time only): twelve logger sink types that declared an
351
+ optional `error` now declare a **non-optional** `warn`, so a durability report
352
+ always has somewhere to land (#9754, #10556).
353
+
354
+ `minor`, not `major`: during the launch window this stack ships breaking changes
355
+ as `minor` — every publishable package versions in lockstep, so a `major` would
356
+ promote the whole release. `patch` would be wrong in the other direction, because
357
+ this *can* break a consumer's build.
358
+
359
+ `error` stays optional on every one of these types — hosts legitimately inject
360
+ reduced sinks, and requiring `error` was measured and rejected as #9754 option C.
361
+ What changes is that its *absence* now has a declared, guaranteed destination.
362
+ Call sites keep the `logger?.warn?.(…)` spelling as the backstop for hosts the
363
+ type cannot reach, so **no runtime behaviour changes**: nothing that printed
364
+ before stops printing, and nothing silent starts printing.
365
+
366
+ ### Who has to change, and what to do
367
+
368
+ Only a caller that hands one of these sinks an object with **no `warn` method** —
369
+ for example `{ info }` or `{ error }` alone. Add a `warn` member; there is no
370
+ rename, no removal, and no stored value or metadata key to rewrite. Every
371
+ construction site inside this repo already supplied one, so the in-repo cost was
372
+ zero; the compile error is reserved for the callers that were silently discarding
373
+ these reports.
374
+
375
+ The affected types, by package:
376
+
377
+ - `@objectstack/cloud-connection` — the internal `PluginContext['logger']`
378
+ - `@objectstack/metadata-protocol` — `IndexMigrationLogger`
379
+ - `@objectstack/plugin-approvals` — the internal `MinimalLogger` of `lifecycle-hooks`
380
+ - `@objectstack/plugin-audit` — `AuthEventAuditLogger`, `ReadAuditLogger`
381
+ - `@objectstack/plugin-auth` — `ReconcileMembershipDeps['logger']`, the internal
382
+ `LoggerLike` of `member-role-canonical`, and `AuthManagerOptions['logger']`
383
+ - `@objectstack/plugin-email` — `ReclaimLogger`, via `ReclaimAttachmentContentOptions`
384
+ - `@objectstack/plugin-reports` — `ReportServiceOptions['logger']`
385
+ - `@objectstack/plugin-sharing` — the internal `MinimalLogger` of `bulk-recompute`,
386
+ `rule-hooks` and `record-share-cascade`
387
+ - `@objectstack/plugin-webhooks` — `OptionalLogger`, via `AutoEnqueuerOptions`
388
+ - `@objectstack/service-knowledge` — `KnowledgeLogger`
389
+
390
+ `AuthManagerOptions['logger']` is the one most likely to be reached from outside:
391
+ `AuthManager` is public surface, its `logger` option stays optional, and a logger
392
+ that *is* supplied must now carry `warn`. The only non-test construction site in
393
+ this repo passes the kernel `Logger`, whose `warn` is already required.
394
+
395
+ `ReportService` and `AutoEnqueuer` additionally stopped defaulting their logger
396
+ field to `{}`. The field is now honestly optional rather than holding an empty
397
+ object that declared it could report and discarded everything. Behaviour is
398
+ unchanged in both directions.
399
+
400
+ <!-- adr-0087: not-required (runtime-interface-only packages/plugins/plugin-auth/src/auth-manager.ts#AuthManagerOptions, packages/plugins/plugin-auth/src/reconcile-membership.ts#ReconcileMembershipDeps, packages/metadata-protocol/src/migrations/partial-index-probe.ts#IndexMigrationLogger, packages/plugins/plugin-audit/src/auth-event-audit.ts#AuthEventAuditLogger, packages/plugins/plugin-audit/src/read-audit.ts#ReadAuditLogger, packages/plugins/plugin-reports/src/report-service.ts#ReportServiceOptions, packages/services/service-knowledge/src/knowledge-service.ts#KnowledgeLogger) every tightened type is a plain TypeScript logger interface -- no Zod projection, no metadata surface, and none is referenced by one -- so `objectstack migrate meta` has nothing to rewrite. Nothing is removed or renamed and no stored value moves; the only consumer action is adding a `warn` member at a construction site the compiler names. -->
401
+
402
+ ### Patch Changes
403
+
404
+ - 6d5c4fa: Release these plugins' resources from `destroy()`, the teardown hook the kernel
405
+ actually calls (#10371). `Plugin` declares `init()`, `start?(ctx)` and
406
+ `destroy?()` — and no `stop()` — so `ObjectKernel.performShutdown()` and
407
+ `LiteKernel.destroy()`, which walk the plugins in reverse calling
408
+ `plugin.destroy()`, walked straight past every plugin whose teardown was spelled
409
+ `stop()`. `await kernel.shutdown()` resolved with the reports dispatcher still
410
+ armed, the REST/OpenAPI/Slack connectors still registered on the automation
411
+ engine, the approvals SLA escalation job still scheduled, and the knowledge
412
+ event-sync subscription still open.
413
+
414
+ Each teardown body now lives in `destroy()`. `stop()` is retained as a
415
+ delegating alias with its parameter made optional, so an embedder that learned
416
+ to call it directly — precisely because the kernel never did — keeps working
417
+ unchanged. No export is removed and the `Plugin` interface is untouched.
418
+
419
+ Same defect as #9371 in `@objectstack/service-messaging`, which surfaced as
420
+ fully green test runs exiting 1 on `EnvironmentTeardownError` and being evicted
421
+ from the merge queue.
422
+ - Updated dependencies [8f04d9a]
423
+ - Updated dependencies [6936d07]
424
+ - Updated dependencies [59eb04d]
425
+ - Updated dependencies [9f05b7d]
426
+ - Updated dependencies [3b2af5e]
427
+ - Updated dependencies [7d2d112]
428
+ - Updated dependencies [5fa0d72]
429
+ - Updated dependencies [02b3b07]
430
+ - Updated dependencies [914c413]
431
+ - Updated dependencies [55809a0]
432
+ - Updated dependencies [ee2ff45]
433
+ - Updated dependencies [47cd3ec]
434
+ - Updated dependencies [52db1d1]
435
+ - Updated dependencies [5649efb]
436
+ - Updated dependencies [9d7d2de]
437
+ - Updated dependencies [c815c50]
438
+ - Updated dependencies [795ea05]
439
+ - Updated dependencies [2306a76]
440
+ - Updated dependencies [e5ea701]
441
+ - Updated dependencies [a40dcc1]
442
+ - Updated dependencies [def0d3e]
443
+ - Updated dependencies [8d0bb79]
444
+ - Updated dependencies [5acb58d]
445
+ - Updated dependencies [2e3cf95]
446
+ - Updated dependencies [4c93387]
447
+ - Updated dependencies [504c8d5]
448
+ - Updated dependencies [a037f7c]
449
+ - Updated dependencies [3ee8ddf]
450
+ - Updated dependencies [16cef97]
451
+ - Updated dependencies [a79bd35]
452
+ - Updated dependencies [6ceaa4b]
453
+ - Updated dependencies [15ea214]
454
+ - Updated dependencies [de19489]
455
+ - Updated dependencies [c684d00]
456
+ - Updated dependencies [923c424]
457
+ - Updated dependencies [0ab81d1]
458
+ - Updated dependencies [1ec36b7]
459
+ - Updated dependencies [5f2e54c]
460
+ - Updated dependencies [189373b]
461
+ - Updated dependencies [35ad101]
462
+ - Updated dependencies [ceb33a9]
463
+ - Updated dependencies [dccbcec]
464
+ - Updated dependencies [73d9795]
465
+ - Updated dependencies [8012960]
466
+ - Updated dependencies [266654d]
467
+ - Updated dependencies [f34f56b]
468
+ - Updated dependencies [f399618]
469
+ - Updated dependencies [75e9301]
470
+ - Updated dependencies [2810695]
471
+ - @objectstack/platform-objects@17.2.0
472
+ - @objectstack/spec@17.2.0
473
+ - @objectstack/core@17.2.0
474
+
3
475
  ## 17.1.0
4
476
 
5
477
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -76,9 +76,16 @@ interface ReportServiceOptions {
76
76
  engine: ReportEngine;
77
77
  email?: ReportEmail;
78
78
  clock?: ReportClock;
79
+ /**
80
+ * `warn` is GUARANTEED, `error` is not (#9754). Hosts do inject reduced sinks,
81
+ * so `error` stays optional — but a durability report that degrades to `warn`
82
+ * needs `warn` to actually be there, and this service degrades to it in eight
83
+ * places below. The whole `logger` stays optional; what is no longer
84
+ * representable is a sink that HAS the field and still prints nothing.
85
+ */
79
86
  logger?: {
80
87
  info?: (msg: any, ...rest: any[]) => void;
81
- warn?: (msg: any, ...rest: any[]) => void;
88
+ warn: (msg: any, ...rest: any[]) => void;
82
89
  error?: (msg: any, ...rest: any[]) => void;
83
90
  };
84
91
  /** Cap rows per report to protect both DB and email size. */
@@ -109,7 +116,22 @@ declare class ReportService implements IReportService {
109
116
  private readonly engine;
110
117
  private readonly email?;
111
118
  private readonly clock;
112
- private readonly logger;
119
+ /**
120
+ * Optional, and deliberately NOT defaulted to `{}` (#10556).
121
+ *
122
+ * `ReportServiceOptions['logger']` guarantees a `warn` channel under #9754, so `{}` stopped being a
123
+ * legal value of the type — which is the gate working: an empty object is a
124
+ * sink that declares it can report and then discards everything. The repair
125
+ * is to say what is TRUE — there may be no logger at all — rather than to
126
+ * mint a sink that lies. Runtime behaviour is unchanged in both directions:
127
+ * absent logger and `{}` both printed nothing before, and print nothing now.
128
+ *
129
+ * ⛔ What this deliberately does NOT decide: whether an absent host sink should
130
+ * instead default to a `console`-backed one. That is the open design call the
131
+ * #9754 ledger records against `plugin-security`'s `= {}` field, and it is a
132
+ * maintainer decision — not something to settle here to make a checker green.
133
+ */
134
+ private readonly logger?;
113
135
  private readonly maxRows;
114
136
  private readonly resolveOwnerContext?;
115
137
  private readonly canExportFn?;
@@ -214,17 +236,63 @@ interface ReportsPluginOptions {
214
236
  declare class ReportsServicePlugin implements Plugin {
215
237
  name: string;
216
238
  version: string;
217
- type: string;
239
+ type: "standard";
218
240
  dependencies: string[];
219
241
  private readonly options;
220
242
  private service?;
221
243
  private intervalHandle?;
222
244
  private jobName?;
223
245
  private jobService?;
246
+ /**
247
+ * Captured in `init()` because `destroy()` — the hook the kernel actually
248
+ * calls — takes NO `PluginContext` (`Plugin.destroy?(): Promise<void> | void`
249
+ * in core's `types.ts`). Teardown still needs somewhere to report a failed
250
+ * job cancellation, so the logger is held rather than resolved late.
251
+ */
252
+ private logger?;
224
253
  constructor(options?: ReportsPluginOptions);
225
254
  init(ctx: PluginContext): Promise<void>;
226
255
  start(ctx: PluginContext): Promise<void>;
227
- stop(ctx: PluginContext): Promise<void>;
256
+ /**
257
+ * The kernel's teardown hook (`Plugin.destroy?()`, core `types.ts`) — the
258
+ * ONLY teardown entry point `ObjectKernel.performShutdown()` and
259
+ * `LiteKernel.destroy()` invoke.
260
+ *
261
+ * [#10371] IT USED TO BE `stop()`, WHICH NOTHING CALLED. The body below was
262
+ * correct in every respect except its NAME: `Plugin` declares `init()`,
263
+ * `start?()` and `destroy?()` and no `stop()`, so the kernel walked straight
264
+ * past this plugin at shutdown and the dispatcher went on ticking after
265
+ * `await kernel.shutdown()` had resolved. The asymmetry is what hid it:
266
+ * `start()` IS on the interface and does fire, so a `start`/`stop` pair reads
267
+ * as symmetric in review.
268
+ *
269
+ * WHY IT STAYED INVISIBLE, AND WHERE THE BILL LANDS. `start()` `unref()`s the
270
+ * interval, so a long-lived host process still exits and nothing complains in
271
+ * production. Under vitest the worker is alive throughout teardown, so a tick
272
+ * fires after the test file is over, reads through a driver the suite already
273
+ * disconnected, and a console fallback warns; `console.*` inside a worker is
274
+ * an RPC (`onUserConsoleLog`) and one issued after `rpcDone()` snapshotted the
275
+ * pending set is rejected as `EnvironmentTeardownError`. Nothing awaits that
276
+ * promise, so it lands as an unhandled rejection and fails a run in which
277
+ * every test passed. That is the identical defect #9371 fixed in
278
+ * `MessagingServicePlugin` — measured there as two green PRs (334/334 and
279
+ * 337/337) evicted from the merge queue.
280
+ *
281
+ * The job-service branch matters as much as the timer: when `service-job` is
282
+ * installed the dispatcher is a scheduled job rather than a `setInterval`, so
283
+ * a teardown the kernel never reaches leaks whichever of the two this
284
+ * deployment happens to use.
285
+ */
286
+ destroy(): Promise<void>;
287
+ /**
288
+ * Retained alias for {@link destroy}. Kept because it is public API of an
289
+ * exported class, and removing it would break an embedder who learned to call
290
+ * it directly precisely BECAUSE the kernel never did. The parameter is now
291
+ * optional and ignored: `destroy()` takes no context, so teardown reads the
292
+ * logger captured in `init()`. Prefer kernel shutdown; direct callers keep
293
+ * working unchanged.
294
+ */
295
+ stop(_ctx?: PluginContext): Promise<void>;
228
296
  }
229
297
 
230
298
  export { type ReportClock, type ReportEmail, type ReportEngine, ReportService, type ReportServiceOptions, type ReportsPluginOptions, ReportsServicePlugin, renderReport };
package/dist/index.d.ts CHANGED
@@ -76,9 +76,16 @@ interface ReportServiceOptions {
76
76
  engine: ReportEngine;
77
77
  email?: ReportEmail;
78
78
  clock?: ReportClock;
79
+ /**
80
+ * `warn` is GUARANTEED, `error` is not (#9754). Hosts do inject reduced sinks,
81
+ * so `error` stays optional — but a durability report that degrades to `warn`
82
+ * needs `warn` to actually be there, and this service degrades to it in eight
83
+ * places below. The whole `logger` stays optional; what is no longer
84
+ * representable is a sink that HAS the field and still prints nothing.
85
+ */
79
86
  logger?: {
80
87
  info?: (msg: any, ...rest: any[]) => void;
81
- warn?: (msg: any, ...rest: any[]) => void;
88
+ warn: (msg: any, ...rest: any[]) => void;
82
89
  error?: (msg: any, ...rest: any[]) => void;
83
90
  };
84
91
  /** Cap rows per report to protect both DB and email size. */
@@ -109,7 +116,22 @@ declare class ReportService implements IReportService {
109
116
  private readonly engine;
110
117
  private readonly email?;
111
118
  private readonly clock;
112
- private readonly logger;
119
+ /**
120
+ * Optional, and deliberately NOT defaulted to `{}` (#10556).
121
+ *
122
+ * `ReportServiceOptions['logger']` guarantees a `warn` channel under #9754, so `{}` stopped being a
123
+ * legal value of the type — which is the gate working: an empty object is a
124
+ * sink that declares it can report and then discards everything. The repair
125
+ * is to say what is TRUE — there may be no logger at all — rather than to
126
+ * mint a sink that lies. Runtime behaviour is unchanged in both directions:
127
+ * absent logger and `{}` both printed nothing before, and print nothing now.
128
+ *
129
+ * ⛔ What this deliberately does NOT decide: whether an absent host sink should
130
+ * instead default to a `console`-backed one. That is the open design call the
131
+ * #9754 ledger records against `plugin-security`'s `= {}` field, and it is a
132
+ * maintainer decision — not something to settle here to make a checker green.
133
+ */
134
+ private readonly logger?;
113
135
  private readonly maxRows;
114
136
  private readonly resolveOwnerContext?;
115
137
  private readonly canExportFn?;
@@ -214,17 +236,63 @@ interface ReportsPluginOptions {
214
236
  declare class ReportsServicePlugin implements Plugin {
215
237
  name: string;
216
238
  version: string;
217
- type: string;
239
+ type: "standard";
218
240
  dependencies: string[];
219
241
  private readonly options;
220
242
  private service?;
221
243
  private intervalHandle?;
222
244
  private jobName?;
223
245
  private jobService?;
246
+ /**
247
+ * Captured in `init()` because `destroy()` — the hook the kernel actually
248
+ * calls — takes NO `PluginContext` (`Plugin.destroy?(): Promise<void> | void`
249
+ * in core's `types.ts`). Teardown still needs somewhere to report a failed
250
+ * job cancellation, so the logger is held rather than resolved late.
251
+ */
252
+ private logger?;
224
253
  constructor(options?: ReportsPluginOptions);
225
254
  init(ctx: PluginContext): Promise<void>;
226
255
  start(ctx: PluginContext): Promise<void>;
227
- stop(ctx: PluginContext): Promise<void>;
256
+ /**
257
+ * The kernel's teardown hook (`Plugin.destroy?()`, core `types.ts`) — the
258
+ * ONLY teardown entry point `ObjectKernel.performShutdown()` and
259
+ * `LiteKernel.destroy()` invoke.
260
+ *
261
+ * [#10371] IT USED TO BE `stop()`, WHICH NOTHING CALLED. The body below was
262
+ * correct in every respect except its NAME: `Plugin` declares `init()`,
263
+ * `start?()` and `destroy?()` and no `stop()`, so the kernel walked straight
264
+ * past this plugin at shutdown and the dispatcher went on ticking after
265
+ * `await kernel.shutdown()` had resolved. The asymmetry is what hid it:
266
+ * `start()` IS on the interface and does fire, so a `start`/`stop` pair reads
267
+ * as symmetric in review.
268
+ *
269
+ * WHY IT STAYED INVISIBLE, AND WHERE THE BILL LANDS. `start()` `unref()`s the
270
+ * interval, so a long-lived host process still exits and nothing complains in
271
+ * production. Under vitest the worker is alive throughout teardown, so a tick
272
+ * fires after the test file is over, reads through a driver the suite already
273
+ * disconnected, and a console fallback warns; `console.*` inside a worker is
274
+ * an RPC (`onUserConsoleLog`) and one issued after `rpcDone()` snapshotted the
275
+ * pending set is rejected as `EnvironmentTeardownError`. Nothing awaits that
276
+ * promise, so it lands as an unhandled rejection and fails a run in which
277
+ * every test passed. That is the identical defect #9371 fixed in
278
+ * `MessagingServicePlugin` — measured there as two green PRs (334/334 and
279
+ * 337/337) evicted from the merge queue.
280
+ *
281
+ * The job-service branch matters as much as the timer: when `service-job` is
282
+ * installed the dispatcher is a scheduled job rather than a `setInterval`, so
283
+ * a teardown the kernel never reaches leaks whichever of the two this
284
+ * deployment happens to use.
285
+ */
286
+ destroy(): Promise<void>;
287
+ /**
288
+ * Retained alias for {@link destroy}. Kept because it is public API of an
289
+ * exported class, and removing it would break an embedder who learned to call
290
+ * it directly precisely BECAUSE the kernel never did. The parameter is now
291
+ * optional and ignored: `destroy()` takes no context, so teardown reads the
292
+ * logger captured in `init()`. Prefer kernel shutdown; direct callers keep
293
+ * working unchanged.
294
+ */
295
+ stop(_ctx?: PluginContext): Promise<void>;
228
296
  }
229
297
 
230
298
  export { type ReportClock, type ReportEmail, type ReportEngine, ReportService, type ReportServiceOptions, type ReportsPluginOptions, ReportsServicePlugin, renderReport };