Commit dda969c
fix(approvals): auto-cancel a record's pending approvals when the record is deleted (#14061)
* fix(approvals): auto-cancel a record's pending approvals when the record is deleted
Deleting a record left its pending `sys_approval_request` rows in the
approvers' inbox — counted, openable, and pointing at a record id that no
longer resolves. Any object whose approval node declares `lockRecord` walks
the same path, because the lock makes "delete and recreate" the author's only
route to fixing a submitted record.
Per the maintainer ruling: pending requests now transition to a new terminal
`cancelled` status carrying a machine-readable `cancel_reason`, the rows are
KEPT as audit evidence, and they leave the pending count and the inbox's
default view (status write plus a `sys_approval_approver` index clear — the
index is what the approver filter actually resolves through).
The linkage is one global `afterDelete` hook beside the existing global
record-lock hook, so it is platform-level and every "approval + lockRecord"
combination benefits at once. It runs no flow node and mirrors no status back
onto the deleted record; the suspended run is reported and left to the
automation service. Terminal rows are untouched, and the delete itself is
never refused.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015adLit3ZYASJiXwxKG78Wi
* chore(audits): re-certify the tenant write-call-site census after the cancel path
`cancelForDeletedRecord` adds two write call sites (the append-only
`sys_approval_action` insert and the `sys_approval_request` status update), so
the generated census moves 215 -> 217 and its hand-written prose figures move
with it. Regenerated with `node scripts/tenant-audit-census.mjs --write`; the
prose numbers the gate holds to the census (215/143/97) are updated in place.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015adLit3ZYASJiXwxKG78Wi
* test(approvals): declare the new integration test's read options instead of erasing them
`check:query-options-erasure` counted 5 new sites (240 -> 245) from
record-delete-cancel.integration.test.ts. None of them is deliberately
off-contract — they are plain `where` + `context` reads — so the remedy the
gate names is to type them, not to spell them `as unknown as
EngineQueryOptions` (which would claim a contract bypass that is not
happening) and not to raise the ratchet.
Each of the five `engine.find` calls now carries `satisfies
EngineQueryOptions`. Verified it is a real check rather than decoration: the
file compiles clean under a tsconfig that includes it, and planting the #4674
shape the rule exists for (`direction: 'desc'`, an undeclared key) turns it
red with TS2353. The ratchet is back at its 240 ceiling, unraised.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015adLit3ZYASJiXwxKG78Wi
* docs(permissions): re-anchor the system-context census after the approvals insertions
`check-system-context-census` reported 20 problems (10 site-without-a-row + 10
anchor-is-not-a-read-site) across plugin-approvals. Triaged all 20 against
`origin/main` before touching anything: every one of the 10 sites exists
verbatim in main's copy of the same file, and the 10 stale anchors are exactly
main's line numbers for those same sites. So this is pure line rot from the
`cancelForDeletedRecord` / `RECORD_DELETE_CANCEL_LIMIT` / `bindRecordDeleteCancelHook`
insertions pushing existing reads down — zero new elevation reads on this
branch, which the gate confirms independently by holding the site count at 109.
In particular `lifecycle-hooks.ts:570` is NOT new code: it is the pre-existing
`bindDelegationWriteGuard` system bypass (#1322 / #4839), main line 440.
Repaired with the sanctioned `node scripts/check-system-context-census.mjs --fix`
— anchors only. No `isSystem` check was deleted, weakened or re-worded, and no
row's prose changed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015adLit3ZYASJiXwxKG78Wi
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 96e25a8 commit dda969c
17 files changed
Lines changed: 958 additions & 37 deletions
File tree
- .changeset
- content/docs/permissions
- docs/audits
- packages
- plugins/plugin-approvals/src
- translations
- spec
- api-surface
- export-origins
- src/contracts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
146 | | - | |
147 | | - | |
148 | | - | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
101 | | - | |
| 101 | + | |
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
150 | | - | |
| 150 | + | |
151 | 151 | | |
152 | | - | |
153 | | - | |
| 152 | + | |
| 153 | + | |
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
170 | | - | |
| 170 | + | |
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
| 174 | + | |
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
| |||
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
186 | | - | |
187 | | - | |
| 186 | + | |
| 187 | + | |
188 | 188 | | |
189 | | - | |
| 189 | + | |
190 | 190 | | |
191 | | - | |
| 191 | + | |
192 | 192 | | |
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
| 196 | + | |
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
| 202 | + | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
206 | 206 | | |
207 | | - | |
| 207 | + | |
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| |||
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
227 | | - | |
| 227 | + | |
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| |||
Lines changed: 8 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
33 | | - | |
| 32 | + | |
| 33 | + | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
69 | | - | |
| 69 | + | |
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| |||
0 commit comments