@objectstack/plugin-approvals 17.0.0-rc.3 → 17.0.0-rc.5

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,16 +1,303 @@
1
1
  # @objectstack/plugin-approvals
2
2
 
3
- ## 17.0.0-rc.3
3
+ ## 17.0.0-rc.5
4
4
 
5
5
  ### Patch Changes
6
6
 
7
+ - Updated dependencies [e8f8f6c]
8
+ - Updated dependencies [7f713b6]
9
+ - Updated dependencies [c960170]
10
+ - Updated dependencies [def5919]
11
+ - Updated dependencies [ce0cfe9]
12
+ - Updated dependencies [1363084]
13
+ - @objectstack/spec@17.0.0-rc.5
14
+ - @objectstack/core@17.0.0-rc.5
15
+ - @objectstack/formula@17.0.0-rc.5
16
+ - @objectstack/metadata-core@17.0.0-rc.5
17
+ - @objectstack/platform-objects@17.0.0-rc.5
18
+ - @objectstack/types@17.0.0-rc.5
19
+
20
+ ## 17.0.0-rc.4
21
+
22
+ ### Minor Changes
23
+
24
+ - ddc2527: fix(approvals): the ADR-0044 revise window is a service-owned node type, not a bare `wait` (#3823)
25
+
26
+ #3801 gated `POST /api/v1/automation/:name/runs/:runId/resume` on the **node type**
27
+ that produced the suspension: an `approval` pause declares
28
+ `resumeAuthority: 'service'`, so it continues only through `ApprovalService`.
29
+ ADR-0044's **revise window** was the same trust boundary in a shape that key
30
+ could not see. Send-back parked the run on an ordinary `wait` node the flow
31
+ author placed — correctly `resumeAuthority: 'any'`, because a signal wait is
32
+ _meant_ to be resumable by an external producer — and `ApprovalService.resubmit`
33
+ was the only thing that checked anything about continuing it.
34
+
35
+ Demonstrated (not reasoned) against the real engine: a raw `resume(runId)` with
36
+ an **empty body**, from any caller, walked the `resubmit` back-edge into the
37
+ approval node and opened round N+1 with **no submitter check and no `resubmit`
38
+ audit row** (`['submit','revise']` — no third row, ever). Worse, when another
39
+ request was already pending on the record — the exact case `resubmit` refuses
40
+ with `DUPLICATE_REQUEST` _specifically to keep the run alive_ — the raw resume
41
+ went around that guard: the approval node's re-entry failed **after** the engine
42
+ consumed the suspension, and the run was **permanently destroyed** with its
43
+ round-N request stuck `returned` and no resubmit able to reach it.
44
+
45
+ The revise pause is therefore its own node type:
46
+
47
+ - **`approval_revise`** (`APPROVAL_REVISE_NODE_TYPE`), registered by
48
+ `@objectstack/plugin-approvals` alongside the `approval` node, declaring
49
+ `resumeAuthority: 'service'`. It stays a first-class box on the canvas, in the
50
+ run log and in the suspended-run store — only the _reuse_ of `wait` was wrong.
51
+ It takes **no config**: the window ends on the submitter's explicit resubmit,
52
+ never on a signal or timer. The `resumeAuthority` gate itself is unchanged.
53
+ - `sendBack` refuses a `revise` edge whose target is not an `approval_revise`
54
+ node, **before any mutation** (like the existing missing-`revise`-edge check),
55
+ so no run can be parked in a window something else can advance.
56
+ - New gating lint `flow-approval-revise-target-not-service-owned`
57
+ (severity `error`, on `os build` / `os validate` / `os lint` and the runtime
58
+ metadata publish gate) rejects the old shape at authoring time.
59
+
60
+ **Upgrading a flow authored against the original ADR-0044 D3.** One token:
61
+
62
+ - **FROM:** `{ id: 'wait_revision', type: 'wait', waitEventConfig: { eventType: 'signal', … } }`
63
+ - **TO:** `{ id: 'wait_revision', type: 'approval_revise' }` — drop
64
+ `waitEventConfig` / any `config`; the window has no event to wait on.
65
+
66
+ Until you do, such a flow keeps registering and running and its approvals stay
67
+ decidable (`approve` / `reject` / `recall` / `reassign` are untouched), but
68
+ **send-back is refused** with a message naming the node and this fix, and
69
+ re-publishing it reports the lint error. A run _already parked_ in a legacy
70
+ revise window keeps its recorded node type (a republish never re-types a live
71
+ pause) and is drained by `resubmit` or `recall` as usual.
72
+
73
+ ADR-0044's 2026-07-28 amendment records the reversal of its D3 and of its
74
+ `Alternatives` rejection of a service-owned revise pause, with the evidence
75
+ above; the implementation section there records what shipped, why the approval
76
+ node does not re-suspend itself instead, and why no ADR-0087 conversion was
77
+ added for the old shape.
78
+
79
+ ### Patch Changes
80
+
81
+ - 7e5ac28: fix(approvals): 删除两处读 `session.roles` 的 admin 豁免 —— 记录锁与委托守卫回到单一权限词汇 (#4839)
82
+
83
+ `plugin-approvals` 的 `lifecycle-hooks.ts` 里有两处 admin 豁免,都读
84
+ `ctx.session.roles`:审批**记录锁**的 `bindApprovalLockHook`,以及
85
+ `sys_approval_delegation` 的 `bindDelegationWriteGuard`。两处都已删除。
86
+
87
+ **这不是行为变更。** `session.roles` 在整个平台没有生产者 —— ObjectQL 的
88
+ `buildSession()` 逐字段构造 session,从不写 `roles` —— 所以两个分支在任何真实引擎
89
+ 路径上都是死代码,记录锁一直就对 admin 生效,委托一直就只能本人管理。删除让代码
90
+ 说出运行时本来就在做的事(spec 的 `HookContext` 声明了 `roles`,消费方在读,生产方
91
+ 从不写:典型的 declared ≠ enforced)。
92
+
93
+ **为什么不是「改用正确判据」而是删除。** `roles.includes('admin')` 还是第二套权限
94
+ 方言:本仓库的权限一律由 ADR-0095 词汇裁决(能力授予 `permissions`、任职
95
+ `positions`、由其派生的 posture),ADR-0090 D3 更是直接禁掉 `role` 这个拼法。同包的
96
+ `ApprovalService.isOverrideActor` 已经这么做了。维护者裁定两处都取「删除」而非改判据:
97
+
98
+ - **记录锁**:admin 释放锁定记录的正规路径已经存在(#3424 —— `recall` /
99
+ `decideNode` 驳回 / `reassign`,全部由 `isOverrideActor` 把关并留痕
100
+ `via_override`)。让审批终结来释放锁,记录就永远不会在审批在途时被改写 —— 这正是
101
+ 合规场景购买记录锁所要的保证。
102
+ - **委托**:最终语义确定为**仅本人管理**(`delegator_id` 必须等于写入者;只有 system
103
+ 上下文旁路)。审批人临时不可用时,替他处置**在途**审批用的是
104
+ `reassign`(把该审批人的名额交给替代人,连 per_group 分组归属一起带过去)/
105
+ `recall` / 驳回。反过来,「替别人建一条委托」本来也做不到这件事:委托只在请求
106
+ **开启**时(`resolveApproverSpec` 内的 `applyOooDelegation`)被查询,对已经挂在该
107
+ 审批人名下的在途审批毫无作用。
108
+
109
+ 新增 `admin-exemption-retired.test.ts`,把上述证据变成可执行断言,并加了一道源码级
110
+ pin:本包非测试源码中不得再出现 `roles` 标识符或与字符串 `'admin'` 的比较。
111
+
112
+ spec 侧 `session.roles` 的退役(至此零消费方)按 ADR-0049 enforce-or-remove 另立协议
113
+ 单处理,不在本次改动内。
114
+
115
+ - 19e1a8f: fix(approvals): an approval decision can no longer strand a flow run silently when no automation engine is attached (#4420)
116
+
117
+ #4420's fix closed every path by which a decision could be recorded while its
118
+ flow stayed parked — except one, and it is the one where none of the new guards
119
+ could run. Every guard it added (`assertRunResumable`'s pre-flight, the
120
+ `RESUME_TARGET_LOST` refusal, the `RESUME_FAILED` throw) hangs off the
121
+ automation engine. In a process where **no engine is attached**, all of them
122
+ were skipped by the same `typeof this.automation?.resume === 'function'`
123
+ condition that wrapped the resume itself — so the decision was written, the
124
+ mirrored status field advanced, and the call answered HTTP 200 with
125
+ `resumed: false` and **nothing logged at all**. That is #4420's reported
126
+ symptom exactly, reproduced in the one composition its fix could not see.
127
+
128
+ The composition is reachable the same way the original bug was: a flow parks at
129
+ an `approval` node in a process that has the automation service, and the
130
+ decision arrives in one that does not (the plugin failed to init, or the host
131
+ was recomposed between releases). The request row still carries a
132
+ `flow_run_id` — which is the row's own declaration that a run is parked on this
133
+ decision.
134
+
135
+ **What changes.** The decision still stands. Rolling it back is not on the
136
+ table (a human really decided, and the row is durable by then), and refusing
137
+ every such call would break the standalone approvals compositions the
138
+ pre-flight deliberately protects — so `finalized` and `resumed` are unchanged
139
+ for every existing caller. What changes is that the gap is no longer silent:
140
+
141
+ - it is logged at **`error`**, per the durability rule in `AGENTS.md` —
142
+ persisted state and runtime state disagree while nothing looks broken from
143
+ the outside, which is the class that rule exists for;
144
+ - the response carries **`resumeError`**, so `resumed: false` arrives with its
145
+ reason and the stranded run's id instead of leaving the caller to guess
146
+ whether a resume was even attempted.
147
+
148
+ It reuses the already-registered `RESUME_FAILED` code and the existing resume
149
+ message shape rather than introducing a new vocabulary — the fact being
150
+ reported (an outcome recorded whose run did not advance) is the same one.
151
+
152
+ Applied at all five sites that resume a recorded outcome: `decide`, the
153
+ revision-limit auto-rejection, `sendBack`, `resubmit`, and both branches of
154
+ `recall` (whose revise-window path needs `cancelRun` rather than `resume`).
155
+
156
+ A request that names **no** run is unaffected and stays quiet — there is
157
+ nothing parked on it, and reporting one there would be the mirror-image
158
+ failure that trains operators to skim `error`.
159
+
160
+ - Updated dependencies [9fe9c1d]
161
+ - Updated dependencies [d4e0809]
162
+ - Updated dependencies [f724f69]
163
+ - Updated dependencies [28ad90e]
164
+ - Updated dependencies [f8644c7]
165
+ - Updated dependencies [306ca50]
166
+ - Updated dependencies [978fed2]
167
+ - Updated dependencies [cfc293f]
168
+ - Updated dependencies [de70b42]
169
+ - Updated dependencies [64cd010]
170
+ - Updated dependencies [fb3d99b]
171
+ - Updated dependencies [cdfbee2]
172
+ - Updated dependencies [29c6c9d]
173
+ - Updated dependencies [d21c001]
174
+ - Updated dependencies [f1cc3a3]
175
+ - Updated dependencies [ddc2527]
176
+ - Updated dependencies [553a47f]
177
+ - Updated dependencies [a3a884d]
178
+ - Updated dependencies [cfed092]
7
179
  - Updated dependencies [2e284b2]
8
- - @objectstack/spec@17.0.0-rc.3
9
- - @objectstack/core@17.0.0-rc.3
10
- - @objectstack/formula@17.0.0-rc.3
11
- - @objectstack/metadata-core@17.0.0-rc.3
12
- - @objectstack/platform-objects@17.0.0-rc.3
13
- - @objectstack/types@17.0.0-rc.3
180
+ - Updated dependencies [1b49eaf]
181
+ - Updated dependencies [0161c7f]
182
+ - Updated dependencies [e900015]
183
+ - Updated dependencies [b5bdf48]
184
+ - Updated dependencies [a019e52]
185
+ - Updated dependencies [64fc6d5]
186
+ - Updated dependencies [b746aa0]
187
+ - Updated dependencies [947d4f9]
188
+ - Updated dependencies [eaaf03c]
189
+ - Updated dependencies [d17df80]
190
+ - Updated dependencies [7d0e7b5]
191
+ - Updated dependencies [6513c17]
192
+ - Updated dependencies [c142ced]
193
+ - Updated dependencies [eda599e]
194
+ - Updated dependencies [c001422]
195
+ - Updated dependencies [77022a9]
196
+ - Updated dependencies [52760bf]
197
+ - Updated dependencies [5543020]
198
+ - Updated dependencies [880d343]
199
+ - Updated dependencies [6e82972]
200
+ - Updated dependencies [4615a18]
201
+ - Updated dependencies [7f62706]
202
+ - Updated dependencies [667fa44]
203
+ - Updated dependencies [37e38d1]
204
+ - Updated dependencies [0f17114]
205
+ - Updated dependencies [1eb13a0]
206
+ - Updated dependencies [c52e608]
207
+ - Updated dependencies [db0d53c]
208
+ - Updated dependencies [4dfd002]
209
+ - Updated dependencies [77be690]
210
+ - Updated dependencies [811c30c]
211
+ - Updated dependencies [b49ccfd]
212
+ - Updated dependencies [85d95e7]
213
+ - Updated dependencies [168f60f]
214
+ - Updated dependencies [244ca86]
215
+ - Updated dependencies [546ab3c]
216
+ - Updated dependencies [58f3220]
217
+ - Updated dependencies [07f1822]
218
+ - Updated dependencies [0b51bb6]
219
+ - Updated dependencies [08f93bc]
220
+ - Updated dependencies [d9971d3]
221
+ - Updated dependencies [eb3e650]
222
+ - Updated dependencies [abeb375]
223
+ - Updated dependencies [ef4efa8]
224
+ - Updated dependencies [cbb6a5c]
225
+ - Updated dependencies [02dc076]
226
+ - Updated dependencies [795b6e1]
227
+ - Updated dependencies [175d789]
228
+ - Updated dependencies [55dbbba]
229
+ - Updated dependencies [72c3c86]
230
+ - Updated dependencies [7f1a635]
231
+ - Updated dependencies [e98fb14]
232
+ - Updated dependencies [0f2fdcd]
233
+ - Updated dependencies [8ffa8b9]
234
+ - Updated dependencies [674ac99]
235
+ - Updated dependencies [1b9a53b]
236
+ - Updated dependencies [502564d]
237
+ - Updated dependencies [471839d]
238
+ - Updated dependencies [46365ab]
239
+ - Updated dependencies [b508244]
240
+ - Updated dependencies [594508e]
241
+ - Updated dependencies [1c625ca]
242
+ - Updated dependencies [71f205d]
243
+ - Updated dependencies [414395b]
244
+ - Updated dependencies [c5adfe1]
245
+ - Updated dependencies [26e1029]
246
+ - Updated dependencies [108ba8d]
247
+ - Updated dependencies [b4ad984]
248
+ - Updated dependencies [a9f32df]
249
+ - Updated dependencies [aeb9b27]
250
+ - Updated dependencies [7d27da0]
251
+ - Updated dependencies [089767f]
252
+ - Updated dependencies [e4c8b6c]
253
+ - Updated dependencies [acb10f6]
254
+ - Updated dependencies [1c3da1f]
255
+ - Updated dependencies [a34fd2e]
256
+ - Updated dependencies [889ae47]
257
+ - Updated dependencies [4f4c3fb]
258
+ - Updated dependencies [7adc841]
259
+ - Updated dependencies [4845f85]
260
+ - Updated dependencies [bf1edef]
261
+ - Updated dependencies [7b005b4]
262
+ - Updated dependencies [94f7b6a]
263
+ - Updated dependencies [5c94f83]
264
+ - Updated dependencies [73e576f]
265
+ - Updated dependencies [c5a5996]
266
+ - Updated dependencies [51a587d]
267
+ - Updated dependencies [ae490ef]
268
+ - Updated dependencies [f61c8cf]
269
+ - Updated dependencies [e3ef52b]
270
+ - Updated dependencies [07f1822]
271
+ - Updated dependencies [04fab5e]
272
+ - Updated dependencies [efedd28]
273
+ - Updated dependencies [5278e11]
274
+ - Updated dependencies [23dba62]
275
+ - Updated dependencies [ba98e26]
276
+ - Updated dependencies [f104bab]
277
+ - Updated dependencies [fc5f536]
278
+ - Updated dependencies [f8cfbb4]
279
+ - Updated dependencies [c89d18c]
280
+ - Updated dependencies [aac90a5]
281
+ - Updated dependencies [1e6ab15]
282
+ - Updated dependencies [c87ef70]
283
+ - Updated dependencies [3cb0618]
284
+ - Updated dependencies [32a0874]
285
+ - Updated dependencies [7055c22]
286
+ - Updated dependencies [785a748]
287
+ - Updated dependencies [3af0354]
288
+ - Updated dependencies [866ff16]
289
+ - Updated dependencies [5a85e67]
290
+ - Updated dependencies [946a131]
291
+ - Updated dependencies [c183a12]
292
+ - Updated dependencies [8064b07]
293
+ - Updated dependencies [4a56dbd]
294
+ - Updated dependencies [06df4fa]
295
+ - @objectstack/spec@17.0.0-rc.4
296
+ - @objectstack/types@17.0.0-rc.4
297
+ - @objectstack/core@17.0.0-rc.4
298
+ - @objectstack/platform-objects@17.0.0-rc.4
299
+ - @objectstack/formula@17.0.0-rc.4
300
+ - @objectstack/metadata-core@17.0.0-rc.4
14
301
 
15
302
  ## 17.0.0-rc.2
16
303