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