@objectstack/plugin-reports 17.0.0-rc.5 → 17.0.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,1687 @@
1
1
  # @objectstack/plugin-reports
2
2
 
3
+ ## 17.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 4ed7ed4: feat(security)!: the export axis is now OPT-IN, explainable, and covers reports (#3544, #3710)
8
+
9
+ **BREAKING — `allowExport` unset no longer means "inherit read".** Reading a
10
+ record and taking a bulk machine-readable copy of the whole table are different
11
+ privileges (Salesforce "Export Reports", Dynamics "Export to Excel", NetSuite
12
+ "Export Lists", SAP `S_GUI` 61 all separate them). The axis now says so.
13
+
14
+ ### Migration — FROM → TO
15
+
16
+ | | before | after |
17
+ | -------------------- | ----------------------------------- | -------------------------- |
18
+ | `allowExport` unset | export **allowed** (inherited read) | export **denied** |
19
+ | `allowExport: false` | export denied | export denied (unchanged) |
20
+ | `allowExport: true` | export allowed | export allowed (unchanged) |
21
+
22
+ **The one-line fix:** add `allowExport: true` to the object entry (or the `'*'`
23
+ wildcard) of every permission set whose holders should keep exporting.
24
+
25
+ ```ts
26
+ objects: {
27
+ deal: { allowRead: true, allowExport: true }, // ← add the grant
28
+ }
29
+ ```
30
+
31
+ Nothing else changes: read, CRUD, RLS, FLS and sharing are untouched, and a set
32
+ that never exported is unaffected.
33
+
34
+ **Who is affected.** Package-shipped sets are re-seeded on upgrade, so the
35
+ built-ins are handled for you — `admin_full_access` and `organization_admin` now
36
+ carry `allowExport: true` explicitly. **Environment-authored sets are not**: any
37
+ custom set whose users export must be edited. `member_default` deliberately does
38
+ NOT carry the grant, so ordinary authenticated users lose export until an admin
39
+ grants it — that is the point of the flip, not an oversight.
40
+
41
+ **Merge semantics.** Most-permissive, exactly like the CRUD bits: any set
42
+ granting `true` grants export. `false` and unset are the same outcome; `false`
43
+ is authoring intent, not a veto, because permission sets are additive capability
44
+ containers (ADR-0090).
45
+
46
+ **Not implied by super-user bits.** `viewAllRecords` / `modifyAllRecords` no
47
+ longer confer export. Separating "may see all data" from "may take a bulk copy"
48
+ is the segregation-of-duties case the axis exists for.
49
+
50
+ ### Also in this change
51
+
52
+ - **spec** — a set carrying `allowExport` is now **high-privilege**
53
+ (`describeHighPrivilegeBits`), so it cannot be bound to the `everyone` /
54
+ `guest` audience anchors. Without this the opt-in was defeatable by binding an
55
+ export-granting set to `everyone`. One predicate, so the runtime anchor gate,
56
+ the `@objectstack/lint` security-posture rule and the install-time suggestion
57
+ surface all pick it up together.
58
+ - **spec / plugin-security** — `ExplainOperationSchema` gains `export`, so
59
+ `explain` can answer _why_ a caller got `403 EXPORT_NOT_PERMITTED`. It
60
+ explains as `read ∧ the export grant`: `object_crud` reports the conjunction
61
+ and attributes the granting set, while every data-shaped layer
62
+ (requiredPermissions, OWD/depth/sharing, RLS, record attribution) is computed
63
+ as the `find` the export actually performs — asking the RLS compiler about an
64
+ `export` operation would match no policy and wrongly report "no RLS applies".
65
+ `readFilter` is surfaced for `export` as it is for `read`.
66
+ - **plugin-reports** — closes the reports side door (#3710). A report rendered
67
+ as `csv`/`json` is the same bulk copy of the same object, so it is gated by
68
+ the same `ISecurityService.canExport`. Enforced in `executeReport`, which the
69
+ interactive run, the ad-hoc run and the scheduled dispatch all funnel through;
70
+ `scheduleReport` additionally refuses at create time so an author is not told
71
+ at 3am. A schedule created while granted stops delivering once the grant is
72
+ revoked. `html_table` stays a read — it is a rendered view, not a bulk copy.
73
+ Deployments without `plugin-security` are unaffected (no permission sets
74
+ exist, so the axis does not apply).
75
+
76
+ <!-- adr-0087: registered export-axis-opt-in -->
77
+
78
+ ### Patch Changes
79
+
80
+ - f40c5b4: refactor(plugin-approvals,plugin-reports): enforcement implementations annotate the full `ExecutionContext` (#7135)
81
+
82
+ The services half of #7070, mirroring what PR #7140 did for
83
+ `plugin-sharing` / `plugin-audit`. #6523 converged 36 contract signatures onto
84
+ the complete `resolveAuthzContext` envelope, applying the #6206 ruling —
85
+ enforcement adjudicates on the whole envelope, never a per-site subset. The
86
+ implementations behind those contracts still annotated their own parameters
87
+ with the six-field shape the contracts used to name, so nothing they could
88
+ _read_ had widened.
89
+
90
+ `ApprovalService`, the approval flow-node provider and `ReportService` now
91
+ declare `ExecutionContext` on all 43 of those positions, and the casts the
92
+ narrow annotation forced are gone:
93
+
94
+ - `isOverrideActor()` read the derived `posture` (ADR-0095) through an
95
+ unchecked `(context as any)`. That gate decides whether a platform or tenant
96
+ admin may release a STUCK approval — one routed to an unstaffed position, the
97
+ only in-product recovery from a permanently locked record — so an erasure sat
98
+ directly on an enforcement input: a mistyped rung would have compiled and
99
+ silently denied every override. It is a declared read now.
100
+ - Both services' `SYSTEM_CTX` is typed as the envelope and passed as itself,
101
+ retiring the `SYSTEM_CTX as unknown as …` double casts at the three sites
102
+ that hand it to a contract method.
103
+ - The `(context as any).userId` / `.tenantId` reads in `ApprovalService` now
104
+ read declared fields.
105
+ - `OwnerContextResolver` returns the envelope, which is what a scheduled report
106
+ actually resolves for its owner (#2849 / #2980).
107
+
108
+ **No runtime behaviour changes.** The values were always complete — this
109
+ family's damage was type-side — so every gate answers exactly what it answered
110
+ before. Method parameters only WIDEN what they accept, so no caller is
111
+ affected, and no public export changes shape.
112
+
113
+ Casts deliberately kept, and now documented where they sit: `organizationId`
114
+ is not a field of the envelope at all — that spelling has its own history
115
+ (#5858 / `check:org-identifier`) and was held out of this change by #7070. In
116
+ `approval-node.ts` the single remaining assertion exists only because the
117
+ literal names that key; it was reduced from `as unknown as …` to a single
118
+ `as ExecutionContext`, which still requires the literal to be comparable to
119
+ the envelope.
120
+
121
+ Because a re-narrowed annotation would compile, ship and pass every test in
122
+ these packages, the convergence is pinned by a new compile-time module per
123
+ package, `exec-context-annotation.pin.ts`: it hands each parameter a fresh
124
+ literal naming envelope-only fields (`posture`, `accessible_org_ids`,
125
+ `org_user_ids`), which TypeScript's excess-property check rejects the moment a
126
+ parameter narrows back, plus negative cases so a parameter erased to `any`
127
+ cannot pass either.
128
+
129
+ The exported `SharingExecutionContext` type itself is NOT removed here: it is
130
+ defined in `packages/spec`, which is single-owner, so its retirement is a
131
+ separate follow-up.
132
+
133
+ - 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
134
+
135
+ The AGENTS.md post-task checklist requires breaking changesets to carry their
136
+ FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
137
+ inside the npm package and is what an upgrading agent greps after the tombstone
138
+ error." That delivery path was severed for 68 of the 69 publishable packages:
139
+ npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
140
+ older npm versions — not `CHANGELOG.md`, and the canonical
141
+ `"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
142
+ 10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
143
+ 70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
144
+ explicitly.
145
+
146
+ The tombstone-error scenario is precisely the one where the repo is out of
147
+ reach — the upgrading agent has `node_modules` and nothing else — so the
148
+ migration text has to ride in the tarball. Every publishable package now
149
+ declares `CHANGELOG.md` in `files`, and the canonical whitelist is
150
+ `["dist", "README.md", "CHANGELOG.md"]`.
151
+
152
+ The other half is the gate: `check:published-files` gains a fifth invariant,
153
+ COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
154
+ always-required lint job, so the next package cannot silently sever the path
155
+ again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
156
+ into the canonical set.
157
+
158
+ Consumer-visible change: one more file per install (the package's changelog,
159
+ e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
160
+ node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
161
+ promised.
162
+
163
+ - b5f9397: fix(sharing,runtime): a `sort` passed straight to the engine never ordered anything; migrate every in-repo engine call to canonical QueryAST keys (#4346)
164
+
165
+ Two changes with different weights, from one sweep of every in-repo engine
166
+ call site that still speaks a deprecated alias.
167
+
168
+ **The bug — three dropped sorts.** #4346 made the engine fold `filter`→`where`
169
+ and `top`→`limit` on all six methods. The other four pairs in
170
+ `RPC_QUERY_ALIAS_SLOTS` (`select`, `sort`, `skip`, `populate`) are folded at
171
+ the RPC/wire layer only — their values need shape lowering that belongs to
172
+ those layers — and a **direct `engine.find()` never crosses that layer**. Three
173
+ call sites passed `sort` there, so it rode onto the AST untouched, every
174
+ driver's `Array.isArray(query.orderBy)` guard declined to emit an ORDER BY, and
175
+ the query returned an ordinary-looking, arbitrarily-ordered result:
176
+
177
+ | call site | asked for | actually got |
178
+ | ----------------------------------- | ------------------------------------------------- | --------------------------- |
179
+ | `share-link-routes.ts` | shared AI conversation messages, `created_at asc` | messages in arbitrary order |
180
+ | `runtime/domains/share-links.ts` | same route, runtime-domain copy | same |
181
+ | `share-link-service.ts` `listLinks` | the 200 most recent share links | an arbitrary 200 |
182
+
183
+ All three combine the dropped sort with a `limit` — the "latest N" shape whose
184
+ failure #4226 spelled out: an unapplied sort returns rows in arbitrary order,
185
+ which `limit` then slices into an arbitrary page. #4226 fixed that in the wire
186
+ normalizer; these calls sit one layer below it. `listLinks` had no test at all,
187
+ which is why it went unnoticed. Now pinned — on the option bag the engine
188
+ receives, not on row order, because the failure is that the key never becomes
189
+ `orderBy` and a fake engine honouring either spelling would pass either way.
190
+
191
+ **The cleanup — 27 no-op renames.** Every remaining in-repo engine call passing
192
+ `filter` now passes `where` (approvals 5, auth 2, reports 6, sharing 11,
193
+ webhooks 2, plus the one `filters` in a spec doc example). These are strict
194
+ no-ops since #4346 folds the alias — the point is that the framework stops
195
+ depending on a spelling it asks users to migrate off, which is a prerequisite
196
+ for ever retiring the aliases. Service-level `filter` PARAMETERS (each
197
+ service's own public API, e.g. `listRequests(filter)`) are deliberately
198
+ untouched — those are not engine option bags.
199
+
200
+ Two of the renamed calls were live victims of the #4346 bug rather than
201
+ cosmetic: `auth-manager`'s `stampIdentitySource` read the table's first row via
202
+ `findOne({filter})` and counted the whole table via `count({filter})`, so a
203
+ federated sign-in never stamped `source: 'idp_provisioned'`. #4346 already
204
+ corrected the behaviour; this makes the call say what it means.
205
+
206
+ - d0d5205: refactor(core,plugin-audit,service-storage,plugin-reports): give the `__` operation-private-key convention a single owner (#7284)
207
+
208
+ `withoutOperationPrivateKeys` — the rule that a consumer forwarding a caller's
209
+ execution envelope to a question about a DIFFERENT object must first drop the
210
+ `__`-prefixed keys plugin-security stamped for the operation in flight — had been
211
+ hand-copied into three packages: `plugin-audit`'s comment access hooks (#7141),
212
+ `service-storage`'s attachment access hooks (#7145) and `plugin-reports`' report
213
+ service (#7204). Each carried its own `OPERATION_PRIVATE_KEY_PREFIX` and its own
214
+ doc block, and the prose had already diverged while the code still agreed — the
215
+ shape that makes a later divergence in behaviour hard to notice.
216
+
217
+ The helper now lives once, in `@objectstack/core`
218
+ (`security/operation-private-keys.ts`), exported from the package root. Core is
219
+ the only candidate all three consumers already depend on: `plugin-security` is
220
+ the producer of the convention and the most honest owner, but none of the three
221
+ depends on it and a string-prefix filter does not justify three new dependency
222
+ edges onto a plugin; `@objectstack/spec` is fenced off by Prime Directive #2. The
223
+ new home sits beside `assemble-execution-context.ts`, which owns the other end of
224
+ the same lifecycle — that file is where an `ExecutionContext` is built at a
225
+ transport entry point, this one is where it is stripped back down before being
226
+ forwarded.
227
+
228
+ The full reasoning moved with the code rather than being thinned: which keys the
229
+ middleware stamps and why each is a widening input, why they are dropped by
230
+ PREFIX and never by a name list, and why the fresh copy is load-bearing in both
231
+ directions. Each consumer keeps only its own local half — which object _its_
232
+ gates actually ask about — and points at the shared home.
233
+
234
+ No behaviour change: the three copies were byte-equivalent, and all three
235
+ packages' suites pass unchanged. Two new pins at the home cover it — the rule's
236
+ own behaviour, which no package-level test had ever asserted directly, and a
237
+ repository-shape pin that turns red if a fourth file declares its own copy.
238
+
239
+ - cc2de0e: chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
240
+
241
+ These 20 packages declared no `files` field, so npm fell back to packing the
242
+ whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
243
+ listed **21 files** — 15 under `src/`, three of them unit tests
244
+ (`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
245
+ build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
246
+ publish time rather than instead of it, so consumers were installing the
247
+ TypeScript sources and the test suite alongside the artifact they asked for.
248
+
249
+ Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
250
+ that already did. Nothing a consumer imports moves: every `main` / `types` /
251
+ `exports` target in all 20 already resolved inside `dist/`, which the new
252
+ `check:published-files` guard verifies rather than assumes. The visible change
253
+ is a smaller install and a smaller dependency-scanning surface — `npm pack` on
254
+ `@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
255
+
256
+ The other half of the fix is the gate. Half the packages declaring `files` and
257
+ half not was the #3786 shape — a hand-copied convention with nothing enforcing
258
+ it, where whoever forgets the line gets no signal at all. `check:published-files`
259
+ (new, wired into the always-required `lint` job) holds every non-private
260
+ workspace package to four invariants: `files` is **declared**; it is
261
+ **sufficient** (covers every entry point, so tightening a whitelist cannot ship
262
+ a package that fails to resolve); it is **minimal** (admits no test, test-harness
263
+ config or build script); and anything beyond `dist` + `README.md` is
264
+ **registered** with a reason, reconciled in both directions so a stale exemption
265
+ is an error rather than dead text. `@objectstack/spec` is the one package with
266
+ registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
267
+ `CHANGELOG.md` are product, not build input.
268
+
269
+ This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
270
+ from the docs-drift implementation test is sound only while no package publishes
271
+ `scripts/` as runtime code; that held, but it held because someone read all three
272
+ offenders by hand. It is now checked on every PR.
273
+
274
+ - cb466aa: Reports read with the caller's whole execution envelope, so a `group`-posture report no longer under-reports
275
+
276
+ `executeReport` rebuilt a five-field projection of the caller's `ExecutionContext`
277
+ (`userId` / `tenantId` / `positions` / `permissions` / `isSystem`) before handing it to
278
+ the engine read that produces the report — while the method's own comment promised
279
+ "reports execute with the caller's identity".
280
+
281
+ **Before.** `accessible_org_ids` was not in that projection, and the engine reads it by
282
+ name (`buildDriverOptions`, ADR-0105 D2 / #3623) to widen the driver's native tenant
283
+ scope to the caller's whole membership set under the `group` tenancy posture. Absent, the
284
+ drivers fall back to active-org equality — "fail toward isolation". So the identical query
285
+ returned the membership union in an interactive list view and collapsed to the active org
286
+ inside a **saved or scheduled** report: silently short rows, no error, nothing in the
287
+ output saying so. Measured end-to-end on a real kernel + SQL driver: three rows across two
288
+ member orgs came back as three interactively and two in the report, and a scheduled CSV
289
+ digest emailed the owner the same two. `timezone` went the same way, so a read-time
290
+ formula field resolved its calendar day in UTC instead of the caller's business timezone;
291
+ `posture`, `org_user_ids`, `systemPermissions` and `onBehalfOf` were dropped too.
292
+
293
+ **After.** The read receives the caller's envelope whole (the #6206 ruling — enforcement
294
+ adjudicates on the whole `resolveAuthzContext` envelope, never a per-site subset), minus
295
+ the `__`-prefixed keys plugin-security stamps for the operation in flight, and as a fresh
296
+ object so a callee's stamp cannot write back into the caller's request context. The same
297
+ shape `plugin-audit` (#7141) and `service-storage` (#7145) landed. Direction is unchanged
298
+ outside `group`: the `isolated` posture, a deployment with no posture provider, and a
299
+ `group` caller with an empty accessible set all still read at active-org equality.
300
+
301
+ - 2c2a212: fix(reports): owner-gate the saved-report schedule routes (#2980)
302
+
303
+ The report read/run/delete routes are owner-isolated (a caller may only touch a
304
+ report they own, denied as `REPORT_NOT_FOUND` to avoid leaking that the id
305
+ exists), but the two schedule routes bypassed that gate: `unscheduleReport` and
306
+ `listSchedules` took the caller `context` as `_context` and never consulted it,
307
+ querying under the system context (RLS-bypassing). Any authenticated caller
308
+ could therefore delete another owner's report schedule — a cross-owner
309
+ destructive write — or list another owner's schedules (leaking recipient
310
+ addresses and cron), by supplying an id.
311
+
312
+ Both now resolve the schedule's parent report and require the caller to own it,
313
+ mirroring the sibling routes:
314
+
315
+ - **`unscheduleReport`** loads the schedule, then its report, and deletes only
316
+ when `canAccessReport` holds; a cross-owner attempt throws `REPORT_NOT_FOUND`
317
+ (mapped to `404` by the REST layer, deny-as-404 anti-enumeration), while a
318
+ genuinely-absent schedule stays idempotent. `scheduleReport` (create) was
319
+ already gated via `getReport`, so only the delete/list doors were open.
320
+ - **`listSchedules`** returns an empty list to any non-system caller who cannot
321
+ access the report it is scoped to — the same non-leaking posture as
322
+ `listReports`. The scheduler's system context still sees every schedule.
323
+
324
+ No authoring-surface or metadata change; existing owner-path behavior is
325
+ unchanged.
326
+
327
+ - dadd1ad: refactor(spec,plugin-sharing): retire the exported `SharingExecutionContext` type (#7218)
328
+
329
+ <!-- adr-0087: registered sharing-execution-context-retired -->
330
+
331
+ **BREAKING — public surface removal.** `SharingExecutionContext` is deleted from
332
+ `@objectstack/spec` (`contracts/sharing-service`) and from
333
+ `@objectstack/plugin-sharing`, which re-exported it. Both `api-surface/` and
334
+ `export-origins/` snapshots are regenerated accordingly.
335
+
336
+ This is the deferred deletion recorded when #7070 split the convergence in two.
337
+ #6523 / PR #7068 converged 36 contract signatures onto the full
338
+ `resolveAuthzContext` envelope (`ExecutionContext`), applying the #6206 ruling —
339
+ enforcement adjudicates on the whole envelope, never a per-site subset. The
340
+ consumer halves then re-annotated the implementations: PR #7140 (identity:
341
+ `plugin-sharing`, `plugin-audit`) and PR #7206 (services: `plugin-approvals`,
342
+ `plugin-reports`). Both landed with the type still exported, because it is
343
+ DEFINED in `packages/spec` and that package's retirement is the spec seat's to
344
+ make. Nothing declares it any more, so it goes.
345
+
346
+ **Migration.** Anyone who imported `SharingExecutionContext` from either package
347
+ should import `ExecutionContext` from `@objectstack/spec` instead — the type the
348
+ contracts have declared since #7068. The old shape was six optional fields, all
349
+ of which exist on the envelope with the same names and types, so a value that
350
+ satisfied the retired type already satisfies `ExecutionContext`; only the
351
+ spelling of the annotation changes.
352
+
353
+ **No runtime behaviour changes.** The type was erased at compile time and no
354
+ signature's accepted shape moved: the contracts already took the wide envelope.
355
+
356
+ **What the retirement did NOT remove — the reason to read the pins.** Deleting
357
+ the type does not make re-narrowing a compile error. Structural subtyping still
358
+ accepts a six-field context where the envelope is expected, so the boundary is
359
+ held by the declared parameter type plus the pins, exactly as before. The three
360
+ `exec-context-annotation.pin.ts` files (`plugin-sharing`, `plugin-approvals`,
361
+ `plugin-reports`) told their failure story as "the parameter narrows back to
362
+ `SharingExecutionContext`", which a deletion would have quietly hollowed out.
363
+ Each now keeps the retired six-field shape as a local, non-exported SPECIMEN
364
+ type and refutes every enforcement parameter against it by type identity, so a
365
+ re-narrowing under ANY name is red — alongside the fresh-literal
366
+ excess-property checks they already carried. `sharing-service.test.ts` in
367
+ `packages/spec` is re-anchored the same way, and its "twin unchanged in shape"
368
+ case becomes a "twin stays retired" case. The narrative the retired type's doc
369
+ block carried (the measured `(context as any).posture` specimen, and why tsc
370
+ cannot police this) moves to the module doc of `contracts/sharing-service`,
371
+ which the contracts and pins now point at.
372
+
373
+ - ea936f3: fix(plugin-reports): `DELETE /api/v1/reports/schedules/:scheduleId` stops telling a caller whether a schedule id exists
374
+
375
+ `DELETE /api/v1/reports/schedules/:scheduleId` answered differently depending on
376
+ whether the target id **existed**, which let any authenticated caller enumerate
377
+ other owners' report schedules by probing ids and reading the status code:
378
+
379
+ | Target | Before | After |
380
+ | ----------------------------------- | ---------------------- | ---------------------------------- |
381
+ | Another owner's schedule id | `404 REPORT_NOT_FOUND` | `404 REPORT_NOT_FOUND` (unchanged) |
382
+ | A schedule id that does not exist | `204 No Content` | `404 REPORT_NOT_FOUND` |
383
+ | A schedule whose report row is gone | `404 REPORT_NOT_FOUND` | `404 REPORT_NOT_FOUND` (unchanged) |
384
+ | Your own schedule | `204 No Content` | `204 No Content` (unchanged) |
385
+
386
+ This is the same defect #7523 closed on the sibling `DELETE /reports/:id`, in the
387
+ costume that card explicitly warned about: there the split was 500-vs-204 and
388
+ loud, here it was 404-vs-204 and read as correct. The route was in fact cited by
389
+ #7523's investigation as the example of the _right_ shape, because it does route
390
+ its catch through `handleValidation` — which is why the cross-owner arm is a
391
+ clean 404 rather than a 500. Only the cross-owner arm was ever probed (QA run
392
+ #7515); the unknown-id arm was not, so the surviving half went unseen and
393
+ `packages/rest/src/rest.test.ts` pinned its `204` green.
394
+
395
+ `ReportService.unscheduleReport()` carried the intent — _"others get a not-found
396
+ so the delete neither fires nor reveals the schedule's existence"_ — and a hole
397
+ one line wide above it: `if (!schedule) return; // idempotent`. Idempotence is
398
+ only harmless where every caller may see the row; with a cross-owner arm that
399
+ throws, resolving quietly _is_ the tell.
400
+
401
+ Both deny arms are now one decision, taken before the delete fires, by the
402
+ predicate already blind to the difference between them: `canAccessReport` is
403
+ false for a schedule that does not exist, for one whose report is gone, and for
404
+ one owned by somebody else alike. A single throw site means a single message, so
405
+ the route's single `handleValidation` call emits a single response — status and
406
+ body cannot drift apart.
407
+
408
+ Unlike `deleteReport`, this could not be pre-empted in the route. That one
409
+ collapses its arms with `getReport()`, which is already blind to the same
410
+ difference (#2980); the caller here presents a `scheduleId`, and `IReportService`
411
+ exposes no by-id schedule read to be blind with (`listSchedules` is keyed by
412
+ `reportId`). The blinding therefore lives in the service, and
413
+ `IReportService.unscheduleReport` now states it as a contract obligation rather
414
+ than leaving each implementation to rediscover it.
415
+
416
+ Deleting a schedule you own still answers `204`. Deleting one you cannot see is
417
+ now `404` instead of a silent `204` — the cost of closing the oracle, and in line
418
+ with the cross-owner GET / run / upsert-overwrite / delete arms, which all
419
+ already answer 404. A system/dispatcher context deleting an id with no row now
420
+ gets `REPORT_NOT_FOUND` too, where it previously resolved; no caller in the repo
421
+ relies on that (the route is the only production caller).
422
+
423
+ Tests assert the two deny arms' responses are **EQUAL** rather than pinning each
424
+ arm's status separately, so the plausible half-fix cannot pass through them — a
425
+ mutation that answers both arms 404 with different bodies leaves every per-arm
426
+ status assertion green and turns the equality assertions red.
427
+
428
+ - 2465133: fix(plugins): sweep the service-lookup erasures out of the plugin composition roots, and fix the two alias-only HTTP reads it exposed (#4251 B5)
429
+
430
+ Batch B5 of the #4251 sweep: the seven remaining `packages/plugins/*` composition
431
+ roots. 35 lookup sites that had been erased to `any` now carry the slot's
432
+ contract, so the compiler checks what each plugin actually calls on the service
433
+ it resolved. The ratchet drops 143 sites / 32 files to 108 / 25.
434
+
435
+ **Two real defects, both of the shape this sweep exists to find.** Approvals'
436
+ actionable-link pages (ADR-0043) and sharing's public share-link REST routes each
437
+ read the HTTP server under `http-server` _only_ — the deprecated alias. The
438
+ ledger records `http.server` as canonical and as the only name present on every
439
+ provider path: `runtime.ts`'s `config.server` path registers no alias at all. On
440
+ that path both lookups threw, the surrounding `catch` swallowed it, and the
441
+ routes silently never mounted — approval e-mail action links 404'd and the
442
+ share-link surface was absent, with nothing in the log to say so. Both reads are
443
+ now canonical-first with the alias as fallback, each name in its own `try`
444
+ because `getService` throws on an empty slot (so `a() ?? b()` inside one `try`
445
+ never reaches `b` — the same correction #4393 made in metadata and
446
+ cloud-connection).
447
+
448
+ Typing choices follow the batch method: pure data-plane consumers take the
449
+ narrow contract (`IDataEngine` in reports), consumers that bind hook or
450
+ middleware seams take the engine seen whole (`IObjectQLEngine` in approvals,
451
+ sharing and pinyin-search), and slots with no contract get a **named** local
452
+ surface rather than `any` — plugin-email's `MailSettingsSurface`, and the
453
+ surfaces the consuming packages already declared (`ApprovalMessagingSurface`,
454
+ `SharingSecurityProbe`, `ReportEmail`). A named surface that omits a member
455
+ still makes the compiler name every call site; `any` says nothing.
456
+
457
+ No behaviour change beyond the two alias reads. No contract changes.
458
+
459
+ - Updated dependencies [50616d9]
460
+ - Updated dependencies [430dcc2]
461
+ - Updated dependencies [690ccf2]
462
+ - Updated dependencies [6a67d7a]
463
+ - Updated dependencies [098f4bb]
464
+ - Updated dependencies [333a374]
465
+ - Updated dependencies [9fe9c1d]
466
+ - Updated dependencies [3d5c090]
467
+ - Updated dependencies [e5bd768]
468
+ - Updated dependencies [08b5a3d]
469
+ - Updated dependencies [e027b3e]
470
+ - Updated dependencies [e6ac4bd]
471
+ - Updated dependencies [c2429b0]
472
+ - Updated dependencies [445a0c2]
473
+ - Updated dependencies [d99aeb3]
474
+ - Updated dependencies [f6609e6]
475
+ - Updated dependencies [4727eb8]
476
+ - Updated dependencies [a70358a]
477
+ - Updated dependencies [0ecc656]
478
+ - Updated dependencies [06772eb]
479
+ - Updated dependencies [d4e0809]
480
+ - Updated dependencies [80334c7]
481
+ - Updated dependencies [f63cd09]
482
+ - Updated dependencies [97e7e3c]
483
+ - Updated dependencies [ce5242c]
484
+ - Updated dependencies [a7163ea]
485
+ - Updated dependencies [e6e9379]
486
+ - Updated dependencies [5823d59]
487
+ - Updated dependencies [3140f9c]
488
+ - Updated dependencies [9500ba4]
489
+ - Updated dependencies [fa3d0cf]
490
+ - Updated dependencies [af5a224]
491
+ - Updated dependencies [71f76e1]
492
+ - Updated dependencies [37b1346]
493
+ - Updated dependencies [99736a0]
494
+ - Updated dependencies [fe67e34]
495
+ - Updated dependencies [fdb4f50]
496
+ - Updated dependencies [270650f]
497
+ - Updated dependencies [3aef718]
498
+ - Updated dependencies [1bd5652]
499
+ - Updated dependencies [14252d3]
500
+ - Updated dependencies [7fb436c]
501
+ - Updated dependencies [879ea13]
502
+ - Updated dependencies [8828b9e]
503
+ - Updated dependencies [1ea6bce]
504
+ - Updated dependencies [c1dcacd]
505
+ - Updated dependencies [ad303ed]
506
+ - Updated dependencies [32ccb23]
507
+ - Updated dependencies [f5a4ef0]
508
+ - Updated dependencies [2d3e255]
509
+ - Updated dependencies [a8940e4]
510
+ - Updated dependencies [7d7521f]
511
+ - Updated dependencies [5dc4d02]
512
+ - Updated dependencies [f724f69]
513
+ - Updated dependencies [98877c9]
514
+ - Updated dependencies [98877c9]
515
+ - Updated dependencies [53068c1]
516
+ - Updated dependencies [ee58392]
517
+ - Updated dependencies [f16e54e]
518
+ - Updated dependencies [c44dd5e]
519
+ - Updated dependencies [06be54e]
520
+ - Updated dependencies [28ad90e]
521
+ - Updated dependencies [76d74ec]
522
+ - Updated dependencies [201b31f]
523
+ - Updated dependencies [e6b1b69]
524
+ - Updated dependencies [259459d]
525
+ - Updated dependencies [3f7f14e]
526
+ - Updated dependencies [e2616e0]
527
+ - Updated dependencies [6fdc5c6]
528
+ - Updated dependencies [8b9d71e]
529
+ - Updated dependencies [05154a1]
530
+ - Updated dependencies [33f5e23]
531
+ - Updated dependencies [259af21]
532
+ - Updated dependencies [f8644c7]
533
+ - Updated dependencies [306ca50]
534
+ - Updated dependencies [978fed2]
535
+ - Updated dependencies [cfc293f]
536
+ - Updated dependencies [587fc91]
537
+ - Updated dependencies [de70b42]
538
+ - Updated dependencies [9b6fe7c]
539
+ - Updated dependencies [fb3d99b]
540
+ - Updated dependencies [1986594]
541
+ - Updated dependencies [6968885]
542
+ - Updated dependencies [eaed61f]
543
+ - Updated dependencies [52200b4]
544
+ - Updated dependencies [cdfbee2]
545
+ - Updated dependencies [ad4af62]
546
+ - Updated dependencies [debe2f6]
547
+ - Updated dependencies [d44dbfa]
548
+ - Updated dependencies [29c6c9d]
549
+ - Updated dependencies [d21c001]
550
+ - Updated dependencies [ad047d2]
551
+ - Updated dependencies [8c711fb]
552
+ - Updated dependencies [f1cc3a3]
553
+ - Updated dependencies [09e4547]
554
+ - Updated dependencies [97b0798]
555
+ - Updated dependencies [474fe39]
556
+ - Updated dependencies [0bc685a]
557
+ - Updated dependencies [b949059]
558
+ - Updated dependencies [2826d1e]
559
+ - Updated dependencies [be1c52c]
560
+ - Updated dependencies [c5ff96d]
561
+ - Updated dependencies [5a84d41]
562
+ - Updated dependencies [84e7be9]
563
+ - Updated dependencies [91f4c78]
564
+ - Updated dependencies [ddc2527]
565
+ - Updated dependencies [820eff9]
566
+ - Updated dependencies [a6c3f38]
567
+ - Updated dependencies [5fa04fb]
568
+ - Updated dependencies [debc23a]
569
+ - Updated dependencies [0f8ad09]
570
+ - Updated dependencies [553a47f]
571
+ - Updated dependencies [43a7a8d]
572
+ - Updated dependencies [a98085f]
573
+ - Updated dependencies [20b1a9e]
574
+ - Updated dependencies [344a22a]
575
+ - Updated dependencies [4827e91]
576
+ - Updated dependencies [8d895ff]
577
+ - Updated dependencies [86f7a20]
578
+ - Updated dependencies [a3a884d]
579
+ - Updated dependencies [cfed092]
580
+ - Updated dependencies [203a449]
581
+ - Updated dependencies [8f9689f]
582
+ - Updated dependencies [73f69dc]
583
+ - Updated dependencies [04c56aa]
584
+ - Updated dependencies [f6472d7]
585
+ - Updated dependencies [57a3bb3]
586
+ - Updated dependencies [b3efeb7]
587
+ - Updated dependencies [ddd075a]
588
+ - Updated dependencies [88154be]
589
+ - Updated dependencies [e8dc61e]
590
+ - Updated dependencies [9c82146]
591
+ - Updated dependencies [5f9a987]
592
+ - Updated dependencies [744b8f5]
593
+ - Updated dependencies [ac37fc6]
594
+ - Updated dependencies [9f060e5]
595
+ - Updated dependencies [bc17d39]
596
+ - Updated dependencies [2f3e793]
597
+ - Updated dependencies [4820f55]
598
+ - Updated dependencies [462d9c4]
599
+ - Updated dependencies [78caf51]
600
+ - Updated dependencies [7d21581]
601
+ - Updated dependencies [37785ed]
602
+ - Updated dependencies [62a789b]
603
+ - Updated dependencies [2e284b2]
604
+ - Updated dependencies [d8e8d9c]
605
+ - Updated dependencies [789ad63]
606
+ - Updated dependencies [f2445c9]
607
+ - Updated dependencies [94e749b]
608
+ - Updated dependencies [ea1d916]
609
+ - Updated dependencies [2af1988]
610
+ - Updated dependencies [0af50a3]
611
+ - Updated dependencies [1b49eaf]
612
+ - Updated dependencies [ae31a19]
613
+ - Updated dependencies [2e836de]
614
+ - Updated dependencies [e0f300b]
615
+ - Updated dependencies [0161c7f]
616
+ - Updated dependencies [e900015]
617
+ - Updated dependencies [db02d47]
618
+ - Updated dependencies [b5bdf48]
619
+ - Updated dependencies [23338c3]
620
+ - Updated dependencies [12a19a8]
621
+ - Updated dependencies [5b843fb]
622
+ - Updated dependencies [62b6a2f]
623
+ - Updated dependencies [7e5af5c]
624
+ - Updated dependencies [5b4780b]
625
+ - Updated dependencies [a933452]
626
+ - Updated dependencies [9d1d9c7]
627
+ - Updated dependencies [8140915]
628
+ - Updated dependencies [a019e52]
629
+ - Updated dependencies [e8f8f6c]
630
+ - Updated dependencies [41dcda3]
631
+ - Updated dependencies [7b48cf9]
632
+ - Updated dependencies [b5404f4]
633
+ - Updated dependencies [64fc6d5]
634
+ - Updated dependencies [b746aa0]
635
+ - Updated dependencies [b4487aa]
636
+ - Updated dependencies [1007379]
637
+ - Updated dependencies [65ca83a]
638
+ - Updated dependencies [0bfdf46]
639
+ - Updated dependencies [947d4f9]
640
+ - Updated dependencies [f764691]
641
+ - Updated dependencies [e120a5a]
642
+ - Updated dependencies [e5bd2f6]
643
+ - Updated dependencies [e650d67]
644
+ - Updated dependencies [04476e7]
645
+ - Updated dependencies [67bf2e2]
646
+ - Updated dependencies [eaaf03c]
647
+ - Updated dependencies [d17df80]
648
+ - Updated dependencies [7d0e7b5]
649
+ - Updated dependencies [c6d1cb4]
650
+ - Updated dependencies [6513c17]
651
+ - Updated dependencies [36030ff]
652
+ - Updated dependencies [79228cd]
653
+ - Updated dependencies [6117f7b]
654
+ - Updated dependencies [e533b0b]
655
+ - Updated dependencies [cdf4d9a]
656
+ - Updated dependencies [aee1806]
657
+ - Updated dependencies [c13350b]
658
+ - Updated dependencies [c13350b]
659
+ - Updated dependencies [2c1988c]
660
+ - Updated dependencies [9ca2d85]
661
+ - Updated dependencies [c13350b]
662
+ - Updated dependencies [891d345]
663
+ - Updated dependencies [c8124e5]
664
+ - Updated dependencies [a52e2ef]
665
+ - Updated dependencies [5293114]
666
+ - Updated dependencies [376a061]
667
+ - Updated dependencies [c142ced]
668
+ - Updated dependencies [211abdb]
669
+ - Updated dependencies [b3363e9]
670
+ - Updated dependencies [eda599e]
671
+ - Updated dependencies [a1a4140]
672
+ - Updated dependencies [7c7e246]
673
+ - Updated dependencies [2ef1807]
674
+ - Updated dependencies [f35cdc5]
675
+ - Updated dependencies [d03fe25]
676
+ - Updated dependencies [217e2e6]
677
+ - Updated dependencies [2672f85]
678
+ - Updated dependencies [20bc357]
679
+ - Updated dependencies [11066f6]
680
+ - Updated dependencies [916af17]
681
+ - Updated dependencies [84c86fb]
682
+ - Updated dependencies [2a2a9fb]
683
+ - Updated dependencies [86a71d1]
684
+ - Updated dependencies [c001422]
685
+ - Updated dependencies [77022a9]
686
+ - Updated dependencies [d5c75e2]
687
+ - Updated dependencies [03d26f7]
688
+ - Updated dependencies [5966c2a]
689
+ - Updated dependencies [2382580]
690
+ - Updated dependencies [9ea2bc5]
691
+ - Updated dependencies [a2e157c]
692
+ - Updated dependencies [95c4227]
693
+ - Updated dependencies [2a61116]
694
+ - Updated dependencies [52760bf]
695
+ - Updated dependencies [5543020]
696
+ - Updated dependencies [880d343]
697
+ - Updated dependencies [6e82972]
698
+ - Updated dependencies [d4df105]
699
+ - Updated dependencies [4615a18]
700
+ - Updated dependencies [f505689]
701
+ - Updated dependencies [d9fa683]
702
+ - Updated dependencies [606d577]
703
+ - Updated dependencies [4384921]
704
+ - Updated dependencies [e2798fa]
705
+ - Updated dependencies [3c628ce]
706
+ - Updated dependencies [c2d9098]
707
+ - Updated dependencies [0fd8556]
708
+ - Updated dependencies [3c7bcc0]
709
+ - Updated dependencies [4b6cac7]
710
+ - Updated dependencies [7631964]
711
+ - Updated dependencies [ac471a0]
712
+ - Updated dependencies [60ae58e]
713
+ - Updated dependencies [7f62706]
714
+ - Updated dependencies [667fa44]
715
+ - Updated dependencies [37e38d1]
716
+ - Updated dependencies [e906126]
717
+ - Updated dependencies [ce92674]
718
+ - Updated dependencies [08363a0]
719
+ - Updated dependencies [444de5b]
720
+ - Updated dependencies [a227ed7]
721
+ - Updated dependencies [7cb922e]
722
+ - Updated dependencies [1d22114]
723
+ - Updated dependencies [1eb13a0]
724
+ - Updated dependencies [c52e608]
725
+ - Updated dependencies [9613396]
726
+ - Updated dependencies [3f7b4ff]
727
+ - Updated dependencies [74155c7]
728
+ - Updated dependencies [b5f9397]
729
+ - Updated dependencies [ed77493]
730
+ - Updated dependencies [6908830]
731
+ - Updated dependencies [8b06bba]
732
+ - Updated dependencies [58a03d2]
733
+ - Updated dependencies [2bacd1a]
734
+ - Updated dependencies [e47b342]
735
+ - Updated dependencies [4c54037]
736
+ - Updated dependencies [dc530b4]
737
+ - Updated dependencies [9f601e8]
738
+ - Updated dependencies [6a9dec6]
739
+ - Updated dependencies [0f7157b]
740
+ - Updated dependencies [4dc1c7d]
741
+ - Updated dependencies [d9bef45]
742
+ - Updated dependencies [4dfd002]
743
+ - Updated dependencies [f549a0d]
744
+ - Updated dependencies [51c5227]
745
+ - Updated dependencies [82da264]
746
+ - Updated dependencies [f586f1a]
747
+ - Updated dependencies [77be690]
748
+ - Updated dependencies [4ed7ed4]
749
+ - Updated dependencies [9b9b70f]
750
+ - Updated dependencies [f5a9bc2]
751
+ - Updated dependencies [e59786e]
752
+ - Updated dependencies [2fa4ca1]
753
+ - Updated dependencies [bcf1112]
754
+ - Updated dependencies [baeb4f0]
755
+ - Updated dependencies [29488cc]
756
+ - Updated dependencies [881a3cc]
757
+ - Updated dependencies [f5a2320]
758
+ - Updated dependencies [ad6317b]
759
+ - Updated dependencies [811c30c]
760
+ - Updated dependencies [a4a85c8]
761
+ - Updated dependencies [859cb83]
762
+ - Updated dependencies [07a4e26]
763
+ - Updated dependencies [9774b78]
764
+ - Updated dependencies [8a88885]
765
+ - Updated dependencies [deb538f]
766
+ - Updated dependencies [b49ccfd]
767
+ - Updated dependencies [5b89711]
768
+ - Updated dependencies [85d95e7]
769
+ - Updated dependencies [08cd163]
770
+ - Updated dependencies [0c8a22f]
771
+ - Updated dependencies [5f7669e]
772
+ - Updated dependencies [becbe53]
773
+ - Updated dependencies [b127c8b]
774
+ - Updated dependencies [763931e]
775
+ - Updated dependencies [ec975f1]
776
+ - Updated dependencies [168f60f]
777
+ - Updated dependencies [b07d829]
778
+ - Updated dependencies [de9af8a]
779
+ - Updated dependencies [eb4204b]
780
+ - Updated dependencies [a80302a]
781
+ - Updated dependencies [a648e96]
782
+ - Updated dependencies [a47ac06]
783
+ - Updated dependencies [e4c61a7]
784
+ - Updated dependencies [cc60165]
785
+ - Updated dependencies [474f131]
786
+ - Updated dependencies [081aa6f]
787
+ - Updated dependencies [91f4c78]
788
+ - Updated dependencies [050cd82]
789
+ - Updated dependencies [4d552af]
790
+ - Updated dependencies [44d677c]
791
+ - Updated dependencies [c32944d]
792
+ - Updated dependencies [1dd780f]
793
+ - Updated dependencies [e8d0c21]
794
+ - Updated dependencies [244ca86]
795
+ - Updated dependencies [546ab3c]
796
+ - Updated dependencies [c4df271]
797
+ - Updated dependencies [c8d6f6e]
798
+ - Updated dependencies [0b51bb6]
799
+ - Updated dependencies [d9971d3]
800
+ - Updated dependencies [7dc1067]
801
+ - Updated dependencies [4f13be2]
802
+ - Updated dependencies [a41ba5c]
803
+ - Updated dependencies [189854c]
804
+ - Updated dependencies [0e3a226]
805
+ - Updated dependencies [92a67f2]
806
+ - Updated dependencies [9136327]
807
+ - Updated dependencies [bf0ae99]
808
+ - Updated dependencies [eb3e650]
809
+ - Updated dependencies [abeb375]
810
+ - Updated dependencies [cb3b6cd]
811
+ - Updated dependencies [73b7234]
812
+ - Updated dependencies [d2b97c3]
813
+ - Updated dependencies [61cc079]
814
+ - Updated dependencies [45dc446]
815
+ - Updated dependencies [0e96e46]
816
+ - Updated dependencies [c1d44f7]
817
+ - Updated dependencies [59b794f]
818
+ - Updated dependencies [ef4efa8]
819
+ - Updated dependencies [cbb6a5c]
820
+ - Updated dependencies [fc3a36a]
821
+ - Updated dependencies [ab9fb5c]
822
+ - Updated dependencies [69787f0]
823
+ - Updated dependencies [5d022a1]
824
+ - Updated dependencies [042b9ee]
825
+ - Updated dependencies [f985b3f]
826
+ - Updated dependencies [795b6e1]
827
+ - Updated dependencies [d52d4fe]
828
+ - Updated dependencies [742cebb]
829
+ - Updated dependencies [175d789]
830
+ - Updated dependencies [f549a0d]
831
+ - Updated dependencies [524151c]
832
+ - Updated dependencies [427344c]
833
+ - Updated dependencies [8af76ae]
834
+ - Updated dependencies [1d4756e]
835
+ - Updated dependencies [720c5ad]
836
+ - Updated dependencies [a8d1e24]
837
+ - Updated dependencies [b85cc54]
838
+ - Updated dependencies [a36db28]
839
+ - Updated dependencies [7a8476f]
840
+ - Updated dependencies [518ca7a]
841
+ - Updated dependencies [d1cabaa]
842
+ - Updated dependencies [41642b0]
843
+ - Updated dependencies [4cca74c]
844
+ - Updated dependencies [88ef03e]
845
+ - Updated dependencies [9a4932a]
846
+ - Updated dependencies [3f8817a]
847
+ - Updated dependencies [a2443e3]
848
+ - Updated dependencies [e1554b1]
849
+ - Updated dependencies [9e2caf3]
850
+ - Updated dependencies [4856789]
851
+ - Updated dependencies [81ce41a]
852
+ - Updated dependencies [85e1e4e]
853
+ - Updated dependencies [c3f4916]
854
+ - Updated dependencies [55dbbba]
855
+ - Updated dependencies [33e0385]
856
+ - Updated dependencies [dac6a08]
857
+ - Updated dependencies [72c3c86]
858
+ - Updated dependencies [2d8dba3]
859
+ - Updated dependencies [7f1a635]
860
+ - Updated dependencies [2205363]
861
+ - Updated dependencies [09fe58d]
862
+ - Updated dependencies [f9fc874]
863
+ - Updated dependencies [d62f8eb]
864
+ - Updated dependencies [d0a5ceb]
865
+ - Updated dependencies [a7586cd]
866
+ - Updated dependencies [4c5e80e]
867
+ - Updated dependencies [4b5702a]
868
+ - Updated dependencies [011b386]
869
+ - Updated dependencies [e18a162]
870
+ - Updated dependencies [e98fb14]
871
+ - Updated dependencies [394b7a1]
872
+ - Updated dependencies [ce92674]
873
+ - Updated dependencies [0f2fdcd]
874
+ - Updated dependencies [d6d1a50]
875
+ - Updated dependencies [cf2c9b7]
876
+ - Updated dependencies [8ffa8b9]
877
+ - Updated dependencies [d127ff0]
878
+ - Updated dependencies [674ac99]
879
+ - Updated dependencies [833b512]
880
+ - Updated dependencies [1b9a53b]
881
+ - Updated dependencies [36d90fc]
882
+ - Updated dependencies [7777e8f]
883
+ - Updated dependencies [9b86cf6]
884
+ - Updated dependencies [d063a96]
885
+ - Updated dependencies [8825a06]
886
+ - Updated dependencies [5087ac6]
887
+ - Updated dependencies [677b591]
888
+ - Updated dependencies [cf7c694]
889
+ - Updated dependencies [ddd0f06]
890
+ - Updated dependencies [d77d1b7]
891
+ - Updated dependencies [0f9faa2]
892
+ - Updated dependencies [2d1ddf0]
893
+ - Updated dependencies [354b00f]
894
+ - Updated dependencies [3de535b]
895
+ - Updated dependencies [fe2e15a]
896
+ - Updated dependencies [5b79a34]
897
+ - Updated dependencies [502564d]
898
+ - Updated dependencies [603cab8]
899
+ - Updated dependencies [c757854]
900
+ - Updated dependencies [471839d]
901
+ - Updated dependencies [507b92a]
902
+ - Updated dependencies [46365ab]
903
+ - Updated dependencies [b508244]
904
+ - Updated dependencies [df95346]
905
+ - Updated dependencies [3dede58]
906
+ - Updated dependencies [c6b6bb4]
907
+ - Updated dependencies [594508e]
908
+ - Updated dependencies [7cf42fe]
909
+ - Updated dependencies [5966c2a]
910
+ - Updated dependencies [59c544d]
911
+ - Updated dependencies [0045682]
912
+ - Updated dependencies [7309c81]
913
+ - Updated dependencies [2f59da0]
914
+ - Updated dependencies [d56012f]
915
+ - Updated dependencies [f78dd83]
916
+ - Updated dependencies [a2cd18a]
917
+ - Updated dependencies [9051802]
918
+ - Updated dependencies [20bc1ec]
919
+ - Updated dependencies [1c625ca]
920
+ - Updated dependencies [2f8328c]
921
+ - Updated dependencies [2a6c279]
922
+ - Updated dependencies [9319586]
923
+ - Updated dependencies [8c8f0df]
924
+ - Updated dependencies [8ad609c]
925
+ - Updated dependencies [bbee302]
926
+ - Updated dependencies [90c2b15]
927
+ - Updated dependencies [4638aaa]
928
+ - Updated dependencies [0222d3c]
929
+ - Updated dependencies [08863dd]
930
+ - Updated dependencies [071d0dc]
931
+ - Updated dependencies [f293d45]
932
+ - Updated dependencies [56664f5]
933
+ - Updated dependencies [71f205d]
934
+ - Updated dependencies [f067930]
935
+ - Updated dependencies [414395b]
936
+ - Updated dependencies [42eeb7d]
937
+ - Updated dependencies [31cbe90]
938
+ - Updated dependencies [6b7129a]
939
+ - Updated dependencies [c5adfe1]
940
+ - Updated dependencies [97ace2a]
941
+ - Updated dependencies [26e1029]
942
+ - Updated dependencies [0a936ea]
943
+ - Updated dependencies [90bbf25]
944
+ - Updated dependencies [023c00b]
945
+ - Updated dependencies [eb91eba]
946
+ - Updated dependencies [42da73d]
947
+ - Updated dependencies [01e124d]
948
+ - Updated dependencies [ef7b5ef]
949
+ - Updated dependencies [9514767]
950
+ - Updated dependencies [8f20201]
951
+ - Updated dependencies [155507e]
952
+ - Updated dependencies [643b7c7]
953
+ - Updated dependencies [7bba90b]
954
+ - Updated dependencies [8813b90]
955
+ - Updated dependencies [108ba8d]
956
+ - Updated dependencies [2a5f04a]
957
+ - Updated dependencies [4f740b0]
958
+ - Updated dependencies [7ce02eb]
959
+ - Updated dependencies [b4ad984]
960
+ - Updated dependencies [e7a7506]
961
+ - Updated dependencies [a9f32df]
962
+ - Updated dependencies [aeb9b27]
963
+ - Updated dependencies [7d27da0]
964
+ - Updated dependencies [d0d5205]
965
+ - Updated dependencies [1a15893]
966
+ - Updated dependencies [b70e534]
967
+ - Updated dependencies [7e05d8e]
968
+ - Updated dependencies [8f1851e]
969
+ - Updated dependencies [61ea810]
970
+ - Updated dependencies [2233a85]
971
+ - Updated dependencies [67452d1]
972
+ - Updated dependencies [089767f]
973
+ - Updated dependencies [a13827e]
974
+ - Updated dependencies [66d99ec]
975
+ - Updated dependencies [cb43296]
976
+ - Updated dependencies [b61afc1]
977
+ - Updated dependencies [79021fc]
978
+ - Updated dependencies [7733604]
979
+ - Updated dependencies [4921a95]
980
+ - Updated dependencies [40e420f]
981
+ - Updated dependencies [62dd69a]
982
+ - Updated dependencies [d13004a]
983
+ - Updated dependencies [be7360c]
984
+ - Updated dependencies [e15e679]
985
+ - Updated dependencies [2ab1257]
986
+ - Updated dependencies [0fc6219]
987
+ - Updated dependencies [061406d]
988
+ - Updated dependencies [e4c8b6c]
989
+ - Updated dependencies [acb10f6]
990
+ - Updated dependencies [605e190]
991
+ - Updated dependencies [c6c59f1]
992
+ - Updated dependencies [b0e78a8]
993
+ - Updated dependencies [f31cc8d]
994
+ - Updated dependencies [f343dc4]
995
+ - Updated dependencies [8269e32]
996
+ - Updated dependencies [74f7339]
997
+ - Updated dependencies [a6c35a2]
998
+ - Updated dependencies [c2f1002]
999
+ - Updated dependencies [4cc4fb7]
1000
+ - Updated dependencies [97b6658]
1001
+ - Updated dependencies [28d1eb7]
1002
+ - Updated dependencies [06770c0]
1003
+ - Updated dependencies [2c26040]
1004
+ - Updated dependencies [f758cec]
1005
+ - Updated dependencies [5b47ab5]
1006
+ - Updated dependencies [b09d8d9]
1007
+ - Updated dependencies [b09d8d9]
1008
+ - Updated dependencies [8675db6]
1009
+ - Updated dependencies [b09d8d9]
1010
+ - Updated dependencies [27358d5]
1011
+ - Updated dependencies [1c3da1f]
1012
+ - Updated dependencies [c1f344b]
1013
+ - Updated dependencies [3eb1b2b]
1014
+ - Updated dependencies [9c93465]
1015
+ - Updated dependencies [a34fd2e]
1016
+ - Updated dependencies [ebb209c]
1017
+ - Updated dependencies [76bcb83]
1018
+ - Updated dependencies [59b85c0]
1019
+ - Updated dependencies [889ae47]
1020
+ - Updated dependencies [4f4c3fb]
1021
+ - Updated dependencies [78f0be8]
1022
+ - Updated dependencies [6e357ed]
1023
+ - Updated dependencies [d6938bf]
1024
+ - Updated dependencies [35f7fb4]
1025
+ - Updated dependencies [0410522]
1026
+ - Updated dependencies [63b33e6]
1027
+ - Updated dependencies [f163028]
1028
+ - Updated dependencies [814db6d]
1029
+ - Updated dependencies [a5302c7]
1030
+ - Updated dependencies [31e0be9]
1031
+ - Updated dependencies [4bfd455]
1032
+ - Updated dependencies [ffd2ce2]
1033
+ - Updated dependencies [2a44c1d]
1034
+ - Updated dependencies [7084313]
1035
+ - Updated dependencies [f07808c]
1036
+ - Updated dependencies [7ffc3d3]
1037
+ - Updated dependencies [88346ba]
1038
+ - Updated dependencies [4631592]
1039
+ - Updated dependencies [62f8017]
1040
+ - Updated dependencies [32ff033]
1041
+ - Updated dependencies [a831df1]
1042
+ - Updated dependencies [f752ee3]
1043
+ - Updated dependencies [a1b61e0]
1044
+ - Updated dependencies [cd6b9f2]
1045
+ - Updated dependencies [2cb6d3c]
1046
+ - Updated dependencies [af2a095]
1047
+ - Updated dependencies [5ac93d4]
1048
+ - Updated dependencies [695cfbd]
1049
+ - Updated dependencies [0e043d8]
1050
+ - Updated dependencies [93f267f]
1051
+ - Updated dependencies [7445149]
1052
+ - Updated dependencies [ec796d5]
1053
+ - Updated dependencies [071d0dc]
1054
+ - Updated dependencies [0024abf]
1055
+ - Updated dependencies [8dd98bf]
1056
+ - Updated dependencies [e87fea1]
1057
+ - Updated dependencies [c65e529]
1058
+ - Updated dependencies [0848bea]
1059
+ - Updated dependencies [d51bed2]
1060
+ - Updated dependencies [dadd1ad]
1061
+ - Updated dependencies [acbf364]
1062
+ - Updated dependencies [3ca34c1]
1063
+ - Updated dependencies [7adc841]
1064
+ - Updated dependencies [239c3a3]
1065
+ - Updated dependencies [b8b3c64]
1066
+ - Updated dependencies [2f2e63c]
1067
+ - Updated dependencies [4845f85]
1068
+ - Updated dependencies [486d526]
1069
+ - Updated dependencies [94a0bbc]
1070
+ - Updated dependencies [d6bfb3d]
1071
+ - Updated dependencies [8a9c079]
1072
+ - Updated dependencies [7b005b4]
1073
+ - Updated dependencies [cc3555e]
1074
+ - Updated dependencies [a2266a6]
1075
+ - Updated dependencies [d25a0ec]
1076
+ - Updated dependencies [89d7b35]
1077
+ - Updated dependencies [94f7b6a]
1078
+ - Updated dependencies [5c94f83]
1079
+ - Updated dependencies [ea936f3]
1080
+ - Updated dependencies [0c0fbd9]
1081
+ - Updated dependencies [667b83e]
1082
+ - Updated dependencies [f3141d8]
1083
+ - Updated dependencies [5487c20]
1084
+ - Updated dependencies [aa8b847]
1085
+ - Updated dependencies [7687f7b]
1086
+ - Updated dependencies [5a84d41]
1087
+ - Updated dependencies [fd3013a]
1088
+ - Updated dependencies [85ec26d]
1089
+ - Updated dependencies [73e576f]
1090
+ - Updated dependencies [f6476fc]
1091
+ - Updated dependencies [69ac82c]
1092
+ - Updated dependencies [4ac12ef]
1093
+ - Updated dependencies [833ed84]
1094
+ - Updated dependencies [a18abf3]
1095
+ - Updated dependencies [c6a4eeb]
1096
+ - Updated dependencies [1659072]
1097
+ - Updated dependencies [f450ae7]
1098
+ - Updated dependencies [abceb0d]
1099
+ - Updated dependencies [627b188]
1100
+ - Updated dependencies [8d4eae7]
1101
+ - Updated dependencies [c5a5996]
1102
+ - Updated dependencies [0c302a7]
1103
+ - Updated dependencies [b88f5e8]
1104
+ - Updated dependencies [857a6cf]
1105
+ - Updated dependencies [65a3a84]
1106
+ - Updated dependencies [6633337]
1107
+ - Updated dependencies [21676eb]
1108
+ - Updated dependencies [3f296bf]
1109
+ - Updated dependencies [e474853]
1110
+ - Updated dependencies [e9cb9ab]
1111
+ - Updated dependencies [42cc219]
1112
+ - Updated dependencies [d42a92f]
1113
+ - Updated dependencies [569611f]
1114
+ - Updated dependencies [51d74ad]
1115
+ - Updated dependencies [d7e0b42]
1116
+ - Updated dependencies [3510e4a]
1117
+ - Updated dependencies [f00d8d4]
1118
+ - Updated dependencies [5326b36]
1119
+ - Updated dependencies [aa4b90d]
1120
+ - Updated dependencies [ccd9397]
1121
+ - Updated dependencies [503be86]
1122
+ - Updated dependencies [54299ca]
1123
+ - Updated dependencies [ae490ef]
1124
+ - Updated dependencies [e124711]
1125
+ - Updated dependencies [dc61def]
1126
+ - Updated dependencies [bca935b]
1127
+ - Updated dependencies [d92c72d]
1128
+ - Updated dependencies [c54c822]
1129
+ - Updated dependencies [8dcc0f5]
1130
+ - Updated dependencies [75b9e51]
1131
+ - Updated dependencies [f61c8cf]
1132
+ - Updated dependencies [e3ef52b]
1133
+ - Updated dependencies [0a2f233]
1134
+ - Updated dependencies [8621cdd]
1135
+ - Updated dependencies [251e888]
1136
+ - Updated dependencies [07f1822]
1137
+ - Updated dependencies [e336549]
1138
+ - Updated dependencies [3bb9340]
1139
+ - Updated dependencies [1e604c4]
1140
+ - Updated dependencies [04fab5e]
1141
+ - Updated dependencies [183b4c4]
1142
+ - Updated dependencies [7f713b6]
1143
+ - Updated dependencies [d40f43a]
1144
+ - Updated dependencies [2fdb36e]
1145
+ - Updated dependencies [e787608]
1146
+ - Updated dependencies [6f23667]
1147
+ - Updated dependencies [cde1975]
1148
+ - Updated dependencies [0bc685a]
1149
+ - Updated dependencies [20526f5]
1150
+ - Updated dependencies [efedd28]
1151
+ - Updated dependencies [5d21a48]
1152
+ - Updated dependencies [5278e11]
1153
+ - Updated dependencies [c5eef1d]
1154
+ - Updated dependencies [e5e7ee0]
1155
+ - Updated dependencies [23dba62]
1156
+ - Updated dependencies [e0f300b]
1157
+ - Updated dependencies [761a0ba]
1158
+ - Updated dependencies [c960170]
1159
+ - Updated dependencies [19365b7]
1160
+ - Updated dependencies [ba98e26]
1161
+ - Updated dependencies [b7ed26d]
1162
+ - Updated dependencies [a2ebea2]
1163
+ - Updated dependencies [800bdb0]
1164
+ - Updated dependencies [9d4dfc4]
1165
+ - Updated dependencies [1059965]
1166
+ - Updated dependencies [def5919]
1167
+ - Updated dependencies [ee264b2]
1168
+ - Updated dependencies [60b672e]
1169
+ - Updated dependencies [f104bab]
1170
+ - Updated dependencies [68dea0b]
1171
+ - Updated dependencies [6b441a8]
1172
+ - Updated dependencies [64f8cbe]
1173
+ - Updated dependencies [6cb81c7]
1174
+ - Updated dependencies [61282f9]
1175
+ - Updated dependencies [ce0cfe9]
1176
+ - Updated dependencies [04f1182]
1177
+ - Updated dependencies [3a2dde7]
1178
+ - Updated dependencies [8c20f75]
1179
+ - Updated dependencies [be87153]
1180
+ - Updated dependencies [dd0f681]
1181
+ - Updated dependencies [60f0dd8]
1182
+ - Updated dependencies [a87c5cd]
1183
+ - Updated dependencies [a47f338]
1184
+ - Updated dependencies [b3a3d83]
1185
+ - Updated dependencies [7a55913]
1186
+ - Updated dependencies [35accbf]
1187
+ - Updated dependencies [6038de7]
1188
+ - Updated dependencies [fc5f536]
1189
+ - Updated dependencies [5647006]
1190
+ - Updated dependencies [e654bfd]
1191
+ - Updated dependencies [01a7337]
1192
+ - Updated dependencies [b45c71e]
1193
+ - Updated dependencies [d71ff32]
1194
+ - Updated dependencies [f8cfbb4]
1195
+ - Updated dependencies [6e6c872]
1196
+ - Updated dependencies [2598216]
1197
+ - Updated dependencies [11949fc]
1198
+ - Updated dependencies [2c7e62d]
1199
+ - Updated dependencies [eb95d97]
1200
+ - Updated dependencies [b098b0e]
1201
+ - Updated dependencies [4d00b13]
1202
+ - Updated dependencies [1363084]
1203
+ - Updated dependencies [fa5758e]
1204
+ - Updated dependencies [38f7e4f]
1205
+ - Updated dependencies [eb7613c]
1206
+ - Updated dependencies [c57f3cf]
1207
+ - Updated dependencies [ecc9110]
1208
+ - Updated dependencies [9aa5510]
1209
+ - Updated dependencies [e4c2dc8]
1210
+ - Updated dependencies [97faca3]
1211
+ - Updated dependencies [57bab76]
1212
+ - Updated dependencies [c89d18c]
1213
+ - Updated dependencies [1bd2795]
1214
+ - Updated dependencies [f7bd4e2]
1215
+ - Updated dependencies [361bd5b]
1216
+ - Updated dependencies [aac90a5]
1217
+ - Updated dependencies [3da3da5]
1218
+ - Updated dependencies [1e6ab15]
1219
+ - Updated dependencies [b90086a]
1220
+ - Updated dependencies [8186a70]
1221
+ - Updated dependencies [a329cca]
1222
+ - Updated dependencies [c87ef70]
1223
+ - Updated dependencies [3cb0618]
1224
+ - Updated dependencies [32a0874]
1225
+ - Updated dependencies [6eec18c]
1226
+ - Updated dependencies [4d7bebf]
1227
+ - Updated dependencies [821ac7a]
1228
+ - Updated dependencies [8f81731]
1229
+ - Updated dependencies [7055c22]
1230
+ - Updated dependencies [785a748]
1231
+ - Updated dependencies [3af0354]
1232
+ - Updated dependencies [866ff16]
1233
+ - Updated dependencies [5a85e67]
1234
+ - Updated dependencies [8b50cb3]
1235
+ - Updated dependencies [a0fdc56]
1236
+ - Updated dependencies [b95577a]
1237
+ - Updated dependencies [0dcbc11]
1238
+ - Updated dependencies [d88f3e9]
1239
+ - Updated dependencies [ad5fe25]
1240
+ - Updated dependencies [c183a12]
1241
+ - Updated dependencies [83c161f]
1242
+ - Updated dependencies [d8c4957]
1243
+ - Updated dependencies [b9f930b]
1244
+ - Updated dependencies [f24cb83]
1245
+ - Updated dependencies [5dbbb92]
1246
+ - Updated dependencies [ea90179]
1247
+ - Updated dependencies [1818998]
1248
+ - Updated dependencies [ce92674]
1249
+ - Updated dependencies [5ef0b5b]
1250
+ - Updated dependencies [8c2db68]
1251
+ - Updated dependencies [22b5e54]
1252
+ - Updated dependencies [0166bd5]
1253
+ - Updated dependencies [8064b07]
1254
+ - Updated dependencies [09ee21c]
1255
+ - Updated dependencies [4a56dbd]
1256
+ - Updated dependencies [289d04a]
1257
+ - Updated dependencies [f549a0d]
1258
+ - Updated dependencies [48fbacb]
1259
+ - Updated dependencies [06df4fa]
1260
+ - Updated dependencies [3fc2e48]
1261
+ - Updated dependencies [c9b809f]
1262
+ - Updated dependencies [e8f435c]
1263
+ - Updated dependencies [32386f8]
1264
+ - Updated dependencies [9b702dc]
1265
+ - Updated dependencies [ab16331]
1266
+ - Updated dependencies [41610f6]
1267
+ - Updated dependencies [69f1dfd]
1268
+ - Updated dependencies [bbe05de]
1269
+ - Updated dependencies [355e951]
1270
+ - Updated dependencies [a1dd1e4]
1271
+ - Updated dependencies [dadb43f]
1272
+ - Updated dependencies [3556b67]
1273
+ - @objectstack/spec@17.0.0
1274
+ - @objectstack/core@17.0.0
1275
+ - @objectstack/platform-objects@17.0.0
1276
+
1277
+ ## 17.0.0-rc.6
1278
+
1279
+ ### Patch Changes
1280
+
1281
+ - f40c5b4: refactor(plugin-approvals,plugin-reports): enforcement implementations annotate the full `ExecutionContext` (#7135)
1282
+
1283
+ The services half of #7070, mirroring what PR #7140 did for
1284
+ `plugin-sharing` / `plugin-audit`. #6523 converged 36 contract signatures onto
1285
+ the complete `resolveAuthzContext` envelope, applying the #6206 ruling —
1286
+ enforcement adjudicates on the whole envelope, never a per-site subset. The
1287
+ implementations behind those contracts still annotated their own parameters
1288
+ with the six-field shape the contracts used to name, so nothing they could
1289
+ _read_ had widened.
1290
+
1291
+ `ApprovalService`, the approval flow-node provider and `ReportService` now
1292
+ declare `ExecutionContext` on all 43 of those positions, and the casts the
1293
+ narrow annotation forced are gone:
1294
+
1295
+ - `isOverrideActor()` read the derived `posture` (ADR-0095) through an
1296
+ unchecked `(context as any)`. That gate decides whether a platform or tenant
1297
+ admin may release a STUCK approval — one routed to an unstaffed position, the
1298
+ only in-product recovery from a permanently locked record — so an erasure sat
1299
+ directly on an enforcement input: a mistyped rung would have compiled and
1300
+ silently denied every override. It is a declared read now.
1301
+ - Both services' `SYSTEM_CTX` is typed as the envelope and passed as itself,
1302
+ retiring the `SYSTEM_CTX as unknown as …` double casts at the three sites
1303
+ that hand it to a contract method.
1304
+ - The `(context as any).userId` / `.tenantId` reads in `ApprovalService` now
1305
+ read declared fields.
1306
+ - `OwnerContextResolver` returns the envelope, which is what a scheduled report
1307
+ actually resolves for its owner (#2849 / #2980).
1308
+
1309
+ **No runtime behaviour changes.** The values were always complete — this
1310
+ family's damage was type-side — so every gate answers exactly what it answered
1311
+ before. Method parameters only WIDEN what they accept, so no caller is
1312
+ affected, and no public export changes shape.
1313
+
1314
+ Casts deliberately kept, and now documented where they sit: `organizationId`
1315
+ is not a field of the envelope at all — that spelling has its own history
1316
+ (#5858 / `check:org-identifier`) and was held out of this change by #7070. In
1317
+ `approval-node.ts` the single remaining assertion exists only because the
1318
+ literal names that key; it was reduced from `as unknown as …` to a single
1319
+ `as ExecutionContext`, which still requires the literal to be comparable to
1320
+ the envelope.
1321
+
1322
+ Because a re-narrowed annotation would compile, ship and pass every test in
1323
+ these packages, the convergence is pinned by a new compile-time module per
1324
+ package, `exec-context-annotation.pin.ts`: it hands each parameter a fresh
1325
+ literal naming envelope-only fields (`posture`, `accessible_org_ids`,
1326
+ `org_user_ids`), which TypeScript's excess-property check rejects the moment a
1327
+ parameter narrows back, plus negative cases so a parameter erased to `any`
1328
+ cannot pass either.
1329
+
1330
+ The exported `SharingExecutionContext` type itself is NOT removed here: it is
1331
+ defined in `packages/spec`, which is single-owner, so its retirement is a
1332
+ separate follow-up.
1333
+
1334
+ - d0d5205: refactor(core,plugin-audit,service-storage,plugin-reports): give the `__` operation-private-key convention a single owner (#7284)
1335
+
1336
+ `withoutOperationPrivateKeys` — the rule that a consumer forwarding a caller's
1337
+ execution envelope to a question about a DIFFERENT object must first drop the
1338
+ `__`-prefixed keys plugin-security stamped for the operation in flight — had been
1339
+ hand-copied into three packages: `plugin-audit`'s comment access hooks (#7141),
1340
+ `service-storage`'s attachment access hooks (#7145) and `plugin-reports`' report
1341
+ service (#7204). Each carried its own `OPERATION_PRIVATE_KEY_PREFIX` and its own
1342
+ doc block, and the prose had already diverged while the code still agreed — the
1343
+ shape that makes a later divergence in behaviour hard to notice.
1344
+
1345
+ The helper now lives once, in `@objectstack/core`
1346
+ (`security/operation-private-keys.ts`), exported from the package root. Core is
1347
+ the only candidate all three consumers already depend on: `plugin-security` is
1348
+ the producer of the convention and the most honest owner, but none of the three
1349
+ depends on it and a string-prefix filter does not justify three new dependency
1350
+ edges onto a plugin; `@objectstack/spec` is fenced off by Prime Directive #2. The
1351
+ new home sits beside `assemble-execution-context.ts`, which owns the other end of
1352
+ the same lifecycle — that file is where an `ExecutionContext` is built at a
1353
+ transport entry point, this one is where it is stripped back down before being
1354
+ forwarded.
1355
+
1356
+ The full reasoning moved with the code rather than being thinned: which keys the
1357
+ middleware stamps and why each is a widening input, why they are dropped by
1358
+ PREFIX and never by a name list, and why the fresh copy is load-bearing in both
1359
+ directions. Each consumer keeps only its own local half — which object _its_
1360
+ gates actually ask about — and points at the shared home.
1361
+
1362
+ No behaviour change: the three copies were byte-equivalent, and all three
1363
+ packages' suites pass unchanged. Two new pins at the home cover it — the rule's
1364
+ own behaviour, which no package-level test had ever asserted directly, and a
1365
+ repository-shape pin that turns red if a fourth file declares its own copy.
1366
+
1367
+ - cb466aa: Reports read with the caller's whole execution envelope, so a `group`-posture report no longer under-reports
1368
+
1369
+ `executeReport` rebuilt a five-field projection of the caller's `ExecutionContext`
1370
+ (`userId` / `tenantId` / `positions` / `permissions` / `isSystem`) before handing it to
1371
+ the engine read that produces the report — while the method's own comment promised
1372
+ "reports execute with the caller's identity".
1373
+
1374
+ **Before.** `accessible_org_ids` was not in that projection, and the engine reads it by
1375
+ name (`buildDriverOptions`, ADR-0105 D2 / #3623) to widen the driver's native tenant
1376
+ scope to the caller's whole membership set under the `group` tenancy posture. Absent, the
1377
+ drivers fall back to active-org equality — "fail toward isolation". So the identical query
1378
+ returned the membership union in an interactive list view and collapsed to the active org
1379
+ inside a **saved or scheduled** report: silently short rows, no error, nothing in the
1380
+ output saying so. Measured end-to-end on a real kernel + SQL driver: three rows across two
1381
+ member orgs came back as three interactively and two in the report, and a scheduled CSV
1382
+ digest emailed the owner the same two. `timezone` went the same way, so a read-time
1383
+ formula field resolved its calendar day in UTC instead of the caller's business timezone;
1384
+ `posture`, `org_user_ids`, `systemPermissions` and `onBehalfOf` were dropped too.
1385
+
1386
+ **After.** The read receives the caller's envelope whole (the #6206 ruling — enforcement
1387
+ adjudicates on the whole `resolveAuthzContext` envelope, never a per-site subset), minus
1388
+ the `__`-prefixed keys plugin-security stamps for the operation in flight, and as a fresh
1389
+ object so a callee's stamp cannot write back into the caller's request context. The same
1390
+ shape `plugin-audit` (#7141) and `service-storage` (#7145) landed. Direction is unchanged
1391
+ outside `group`: the `isolated` posture, a deployment with no posture provider, and a
1392
+ `group` caller with an empty accessible set all still read at active-org equality.
1393
+
1394
+ - 2c2a212: fix(reports): owner-gate the saved-report schedule routes (#2980)
1395
+
1396
+ The report read/run/delete routes are owner-isolated (a caller may only touch a
1397
+ report they own, denied as `REPORT_NOT_FOUND` to avoid leaking that the id
1398
+ exists), but the two schedule routes bypassed that gate: `unscheduleReport` and
1399
+ `listSchedules` took the caller `context` as `_context` and never consulted it,
1400
+ querying under the system context (RLS-bypassing). Any authenticated caller
1401
+ could therefore delete another owner's report schedule — a cross-owner
1402
+ destructive write — or list another owner's schedules (leaking recipient
1403
+ addresses and cron), by supplying an id.
1404
+
1405
+ Both now resolve the schedule's parent report and require the caller to own it,
1406
+ mirroring the sibling routes:
1407
+
1408
+ - **`unscheduleReport`** loads the schedule, then its report, and deletes only
1409
+ when `canAccessReport` holds; a cross-owner attempt throws `REPORT_NOT_FOUND`
1410
+ (mapped to `404` by the REST layer, deny-as-404 anti-enumeration), while a
1411
+ genuinely-absent schedule stays idempotent. `scheduleReport` (create) was
1412
+ already gated via `getReport`, so only the delete/list doors were open.
1413
+ - **`listSchedules`** returns an empty list to any non-system caller who cannot
1414
+ access the report it is scoped to — the same non-leaking posture as
1415
+ `listReports`. The scheduler's system context still sees every schedule.
1416
+
1417
+ No authoring-surface or metadata change; existing owner-path behavior is
1418
+ unchanged.
1419
+
1420
+ - dadd1ad: refactor(spec,plugin-sharing): retire the exported `SharingExecutionContext` type (#7218)
1421
+
1422
+ <!-- adr-0087: registered sharing-execution-context-retired -->
1423
+
1424
+ **BREAKING — public surface removal.** `SharingExecutionContext` is deleted from
1425
+ `@objectstack/spec` (`contracts/sharing-service`) and from
1426
+ `@objectstack/plugin-sharing`, which re-exported it. Both `api-surface/` and
1427
+ `export-origins/` snapshots are regenerated accordingly.
1428
+
1429
+ This is the deferred deletion recorded when #7070 split the convergence in two.
1430
+ #6523 / PR #7068 converged 36 contract signatures onto the full
1431
+ `resolveAuthzContext` envelope (`ExecutionContext`), applying the #6206 ruling —
1432
+ enforcement adjudicates on the whole envelope, never a per-site subset. The
1433
+ consumer halves then re-annotated the implementations: PR #7140 (identity:
1434
+ `plugin-sharing`, `plugin-audit`) and PR #7206 (services: `plugin-approvals`,
1435
+ `plugin-reports`). Both landed with the type still exported, because it is
1436
+ DEFINED in `packages/spec` and that package's retirement is the spec seat's to
1437
+ make. Nothing declares it any more, so it goes.
1438
+
1439
+ **Migration.** Anyone who imported `SharingExecutionContext` from either package
1440
+ should import `ExecutionContext` from `@objectstack/spec` instead — the type the
1441
+ contracts have declared since #7068. The old shape was six optional fields, all
1442
+ of which exist on the envelope with the same names and types, so a value that
1443
+ satisfied the retired type already satisfies `ExecutionContext`; only the
1444
+ spelling of the annotation changes.
1445
+
1446
+ **No runtime behaviour changes.** The type was erased at compile time and no
1447
+ signature's accepted shape moved: the contracts already took the wide envelope.
1448
+
1449
+ **What the retirement did NOT remove — the reason to read the pins.** Deleting
1450
+ the type does not make re-narrowing a compile error. Structural subtyping still
1451
+ accepts a six-field context where the envelope is expected, so the boundary is
1452
+ held by the declared parameter type plus the pins, exactly as before. The three
1453
+ `exec-context-annotation.pin.ts` files (`plugin-sharing`, `plugin-approvals`,
1454
+ `plugin-reports`) told their failure story as "the parameter narrows back to
1455
+ `SharingExecutionContext`", which a deletion would have quietly hollowed out.
1456
+ Each now keeps the retired six-field shape as a local, non-exported SPECIMEN
1457
+ type and refutes every enforcement parameter against it by type identity, so a
1458
+ re-narrowing under ANY name is red — alongside the fresh-literal
1459
+ excess-property checks they already carried. `sharing-service.test.ts` in
1460
+ `packages/spec` is re-anchored the same way, and its "twin unchanged in shape"
1461
+ case becomes a "twin stays retired" case. The narrative the retired type's doc
1462
+ block carried (the measured `(context as any).posture` specimen, and why tsc
1463
+ cannot police this) moves to the module doc of `contracts/sharing-service`,
1464
+ which the contracts and pins now point at.
1465
+
1466
+ - 2465133: fix(plugins): sweep the service-lookup erasures out of the plugin composition roots, and fix the two alias-only HTTP reads it exposed (#4251 B5)
1467
+
1468
+ Batch B5 of the #4251 sweep: the seven remaining `packages/plugins/*` composition
1469
+ roots. 35 lookup sites that had been erased to `any` now carry the slot's
1470
+ contract, so the compiler checks what each plugin actually calls on the service
1471
+ it resolved. The ratchet drops 143 sites / 32 files to 108 / 25.
1472
+
1473
+ **Two real defects, both of the shape this sweep exists to find.** Approvals'
1474
+ actionable-link pages (ADR-0043) and sharing's public share-link REST routes each
1475
+ read the HTTP server under `http-server` _only_ — the deprecated alias. The
1476
+ ledger records `http.server` as canonical and as the only name present on every
1477
+ provider path: `runtime.ts`'s `config.server` path registers no alias at all. On
1478
+ that path both lookups threw, the surrounding `catch` swallowed it, and the
1479
+ routes silently never mounted — approval e-mail action links 404'd and the
1480
+ share-link surface was absent, with nothing in the log to say so. Both reads are
1481
+ now canonical-first with the alias as fallback, each name in its own `try`
1482
+ because `getService` throws on an empty slot (so `a() ?? b()` inside one `try`
1483
+ never reaches `b` — the same correction #4393 made in metadata and
1484
+ cloud-connection).
1485
+
1486
+ Typing choices follow the batch method: pure data-plane consumers take the
1487
+ narrow contract (`IDataEngine` in reports), consumers that bind hook or
1488
+ middleware seams take the engine seen whole (`IObjectQLEngine` in approvals,
1489
+ sharing and pinyin-search), and slots with no contract get a **named** local
1490
+ surface rather than `any` — plugin-email's `MailSettingsSurface`, and the
1491
+ surfaces the consuming packages already declared (`ApprovalMessagingSurface`,
1492
+ `SharingSecurityProbe`, `ReportEmail`). A named surface that omits a member
1493
+ still makes the compiler name every call site; `any` says nothing.
1494
+
1495
+ No behaviour change beyond the two alias reads. No contract changes.
1496
+
1497
+ - Updated dependencies [3d5c090]
1498
+ - Updated dependencies [e5bd768]
1499
+ - Updated dependencies [e027b3e]
1500
+ - Updated dependencies [c2429b0]
1501
+ - Updated dependencies [445a0c2]
1502
+ - Updated dependencies [f6609e6]
1503
+ - Updated dependencies [a70358a]
1504
+ - Updated dependencies [97e7e3c]
1505
+ - Updated dependencies [8828b9e]
1506
+ - Updated dependencies [53068c1]
1507
+ - Updated dependencies [ee58392]
1508
+ - Updated dependencies [f16e54e]
1509
+ - Updated dependencies [06be54e]
1510
+ - Updated dependencies [259459d]
1511
+ - Updated dependencies [3f7f14e]
1512
+ - Updated dependencies [6968885]
1513
+ - Updated dependencies [eaed61f]
1514
+ - Updated dependencies [debe2f6]
1515
+ - Updated dependencies [97b0798]
1516
+ - Updated dependencies [5fa04fb]
1517
+ - Updated dependencies [43a7a8d]
1518
+ - Updated dependencies [73f69dc]
1519
+ - Updated dependencies [04c56aa]
1520
+ - Updated dependencies [b3efeb7]
1521
+ - Updated dependencies [ddd075a]
1522
+ - Updated dependencies [88154be]
1523
+ - Updated dependencies [e8dc61e]
1524
+ - Updated dependencies [2f3e793]
1525
+ - Updated dependencies [d8e8d9c]
1526
+ - Updated dependencies [94e749b]
1527
+ - Updated dependencies [ea1d916]
1528
+ - Updated dependencies [ae31a19]
1529
+ - Updated dependencies [e0f300b]
1530
+ - Updated dependencies [62b6a2f]
1531
+ - Updated dependencies [5b4780b]
1532
+ - Updated dependencies [a933452]
1533
+ - Updated dependencies [8140915]
1534
+ - Updated dependencies [7b48cf9]
1535
+ - Updated dependencies [b5404f4]
1536
+ - Updated dependencies [f764691]
1537
+ - Updated dependencies [e120a5a]
1538
+ - Updated dependencies [e650d67]
1539
+ - Updated dependencies [04476e7]
1540
+ - Updated dependencies [79228cd]
1541
+ - Updated dependencies [b3363e9]
1542
+ - Updated dependencies [2ef1807]
1543
+ - Updated dependencies [d03fe25]
1544
+ - Updated dependencies [2672f85]
1545
+ - Updated dependencies [11066f6]
1546
+ - Updated dependencies [916af17]
1547
+ - Updated dependencies [84c86fb]
1548
+ - Updated dependencies [2a2a9fb]
1549
+ - Updated dependencies [a2e157c]
1550
+ - Updated dependencies [95c4227]
1551
+ - Updated dependencies [2a61116]
1552
+ - Updated dependencies [d4df105]
1553
+ - Updated dependencies [e2798fa]
1554
+ - Updated dependencies [0fd8556]
1555
+ - Updated dependencies [74155c7]
1556
+ - Updated dependencies [6908830]
1557
+ - Updated dependencies [8b06bba]
1558
+ - Updated dependencies [4c54037]
1559
+ - Updated dependencies [0f7157b]
1560
+ - Updated dependencies [d9bef45]
1561
+ - Updated dependencies [f549a0d]
1562
+ - Updated dependencies [82da264]
1563
+ - Updated dependencies [f586f1a]
1564
+ - Updated dependencies [9b9b70f]
1565
+ - Updated dependencies [f5a9bc2]
1566
+ - Updated dependencies [881a3cc]
1567
+ - Updated dependencies [ad6317b]
1568
+ - Updated dependencies [8a88885]
1569
+ - Updated dependencies [5f7669e]
1570
+ - Updated dependencies [becbe53]
1571
+ - Updated dependencies [b127c8b]
1572
+ - Updated dependencies [a80302a]
1573
+ - Updated dependencies [474f131]
1574
+ - Updated dependencies [050cd82]
1575
+ - Updated dependencies [4d552af]
1576
+ - Updated dependencies [44d677c]
1577
+ - Updated dependencies [c32944d]
1578
+ - Updated dependencies [1dd780f]
1579
+ - Updated dependencies [c8d6f6e]
1580
+ - Updated dependencies [92a67f2]
1581
+ - Updated dependencies [9136327]
1582
+ - Updated dependencies [bf0ae99]
1583
+ - Updated dependencies [cb3b6cd]
1584
+ - Updated dependencies [73b7234]
1585
+ - Updated dependencies [d2b97c3]
1586
+ - Updated dependencies [59b794f]
1587
+ - Updated dependencies [fc3a36a]
1588
+ - Updated dependencies [69787f0]
1589
+ - Updated dependencies [5d022a1]
1590
+ - Updated dependencies [042b9ee]
1591
+ - Updated dependencies [f549a0d]
1592
+ - Updated dependencies [a36db28]
1593
+ - Updated dependencies [3f8817a]
1594
+ - Updated dependencies [a2443e3]
1595
+ - Updated dependencies [e1554b1]
1596
+ - Updated dependencies [4856789]
1597
+ - Updated dependencies [c3f4916]
1598
+ - Updated dependencies [33e0385]
1599
+ - Updated dependencies [2205363]
1600
+ - Updated dependencies [09fe58d]
1601
+ - Updated dependencies [d0a5ceb]
1602
+ - Updated dependencies [e18a162]
1603
+ - Updated dependencies [d6d1a50]
1604
+ - Updated dependencies [d127ff0]
1605
+ - Updated dependencies [9b86cf6]
1606
+ - Updated dependencies [8825a06]
1607
+ - Updated dependencies [5087ac6]
1608
+ - Updated dependencies [2d1ddf0]
1609
+ - Updated dependencies [354b00f]
1610
+ - Updated dependencies [3de535b]
1611
+ - Updated dependencies [fe2e15a]
1612
+ - Updated dependencies [c6b6bb4]
1613
+ - Updated dependencies [59c544d]
1614
+ - Updated dependencies [2f59da0]
1615
+ - Updated dependencies [8ad609c]
1616
+ - Updated dependencies [bbee302]
1617
+ - Updated dependencies [08863dd]
1618
+ - Updated dependencies [56664f5]
1619
+ - Updated dependencies [31cbe90]
1620
+ - Updated dependencies [90bbf25]
1621
+ - Updated dependencies [eb91eba]
1622
+ - Updated dependencies [42da73d]
1623
+ - Updated dependencies [643b7c7]
1624
+ - Updated dependencies [d0d5205]
1625
+ - Updated dependencies [1a15893]
1626
+ - Updated dependencies [b70e534]
1627
+ - Updated dependencies [2233a85]
1628
+ - Updated dependencies [62dd69a]
1629
+ - Updated dependencies [e15e679]
1630
+ - Updated dependencies [2ab1257]
1631
+ - Updated dependencies [4cc4fb7]
1632
+ - Updated dependencies [28d1eb7]
1633
+ - Updated dependencies [2c26040]
1634
+ - Updated dependencies [f758cec]
1635
+ - Updated dependencies [78f0be8]
1636
+ - Updated dependencies [35f7fb4]
1637
+ - Updated dependencies [a5302c7]
1638
+ - Updated dependencies [7084313]
1639
+ - Updated dependencies [0e043d8]
1640
+ - Updated dependencies [dadd1ad]
1641
+ - Updated dependencies [2f2e63c]
1642
+ - Updated dependencies [486d526]
1643
+ - Updated dependencies [89d7b35]
1644
+ - Updated dependencies [85ec26d]
1645
+ - Updated dependencies [f6476fc]
1646
+ - Updated dependencies [4ac12ef]
1647
+ - Updated dependencies [b88f5e8]
1648
+ - Updated dependencies [42cc219]
1649
+ - Updated dependencies [d42a92f]
1650
+ - Updated dependencies [51d74ad]
1651
+ - Updated dependencies [d7e0b42]
1652
+ - Updated dependencies [3510e4a]
1653
+ - Updated dependencies [aa4b90d]
1654
+ - Updated dependencies [54299ca]
1655
+ - Updated dependencies [dc61def]
1656
+ - Updated dependencies [251e888]
1657
+ - Updated dependencies [183b4c4]
1658
+ - Updated dependencies [2fdb36e]
1659
+ - Updated dependencies [e787608]
1660
+ - Updated dependencies [20526f5]
1661
+ - Updated dependencies [c5eef1d]
1662
+ - Updated dependencies [e0f300b]
1663
+ - Updated dependencies [761a0ba]
1664
+ - Updated dependencies [61282f9]
1665
+ - Updated dependencies [be87153]
1666
+ - Updated dependencies [60f0dd8]
1667
+ - Updated dependencies [a87c5cd]
1668
+ - Updated dependencies [a47f338]
1669
+ - Updated dependencies [2598216]
1670
+ - Updated dependencies [2c7e62d]
1671
+ - Updated dependencies [eb7613c]
1672
+ - Updated dependencies [ecc9110]
1673
+ - Updated dependencies [f7bd4e2]
1674
+ - Updated dependencies [361bd5b]
1675
+ - Updated dependencies [1818998]
1676
+ - Updated dependencies [09ee21c]
1677
+ - Updated dependencies [f549a0d]
1678
+ - Updated dependencies [3fc2e48]
1679
+ - Updated dependencies [e8f435c]
1680
+ - Updated dependencies [41610f6]
1681
+ - @objectstack/spec@17.0.0-rc.6
1682
+ - @objectstack/platform-objects@17.0.0-rc.6
1683
+ - @objectstack/core@17.0.0-rc.6
1684
+
3
1685
  ## 17.0.0-rc.5
4
1686
 
5
1687
  ### Patch Changes