@@ -17,11 +17,6 @@ import PROMPT_TITLE from "./prompt/title.txt"
1717// altimate_change start - import custom agent mode prompts
1818import PROMPT_BUILDER from "../altimate/prompts/builder.txt"
1919import PROMPT_ANALYST from "../altimate/prompts/analyst.txt"
20- import PROMPT_VALIDATOR from "../altimate/prompts/validator.txt"
21- import PROMPT_MIGRATOR from "../altimate/prompts/migrator.txt"
22- import PROMPT_EXECUTIVE from "../altimate/prompts/executive.txt"
23- import PROMPT_RESEARCHER from "../altimate/prompts/researcher.txt"
24- import PROMPT_TRAINER from "../altimate/prompts/trainer.txt"
2520// altimate_change end
2621import { PermissionNext } from "@/permission/next"
2722import { mergeDeep , pipe , sortBy , values } from "remeda"
@@ -126,13 +121,26 @@ export namespace Agent {
126121 "Drop Schema *" : "deny" ,
127122 "Truncate *" : "deny" ,
128123 } ,
124+ // altimate_change start - SQL write safety denials
125+ sql_execute_write : {
126+ "DROP DATABASE *" : "deny" ,
127+ "DROP SCHEMA *" : "deny" ,
128+ "TRUNCATE *" : "deny" ,
129+ "drop database *" : "deny" ,
130+ "drop schema *" : "deny" ,
131+ "truncate *" : "deny" ,
132+ "Drop Database *" : "deny" ,
133+ "Drop Schema *" : "deny" ,
134+ "Truncate *" : "deny" ,
135+ } ,
136+ // altimate_change end
129137 } )
130138
131139 // Combine user config with safety denials so every agent inherits them
132140 const userWithSafety = PermissionNext . merge ( user , safetyDenials )
133141
134142 const result : Record < string , Info > = {
135- // altimate_change start - replace default build agent with builder and add custom modes
143+ // altimate_change start - 3 modes: builder, analyst, plan
136144 builder : {
137145 name : "builder" ,
138146 description : "Create and modify dbt models, SQL, and data pipelines. Full read/write access." ,
@@ -143,6 +151,7 @@ export namespace Agent {
143151 PermissionNext . fromConfig ( {
144152 question : "allow" ,
145153 plan_enter : "allow" ,
154+ sql_execute_write : "ask" ,
146155 } ) ,
147156 userWithSafety ,
148157 ) ,
@@ -151,178 +160,45 @@ export namespace Agent {
151160 } ,
152161 analyst : {
153162 name : "analyst" ,
154- description : "Read-only data exploration. Cannot modify files or run destructive SQL." ,
163+ description : "Read-only data exploration and analysis . Cannot modify files or run destructive SQL." ,
155164 prompt : PROMPT_ANALYST ,
156165 options : { } ,
157166 permission : PermissionNext . merge (
158167 defaults ,
159168 PermissionNext . fromConfig ( {
160169 "*" : "deny" ,
170+ // SQL read tools
161171 sql_execute : "allow" , sql_validate : "allow" , sql_analyze : "allow" ,
162172 sql_translate : "allow" , sql_optimize : "allow" , lineage_check : "allow" ,
173+ sql_explain : "allow" , sql_format : "allow" , sql_fix : "allow" ,
174+ sql_autocomplete : "allow" , sql_diff : "allow" ,
175+ // SQL writes denied
176+ sql_execute_write : "deny" ,
177+ // Warehouse/schema/finops
163178 warehouse_list : "allow" , warehouse_test : "allow" , warehouse_discover : "allow" ,
164179 schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
165- schema_cache_status : "allow" , sql_explain : "allow" , sql_format : "allow" ,
166- sql_fix : "allow" , sql_autocomplete : "allow" , sql_diff : "allow" ,
180+ schema_cache_status : "allow" , schema_detect_pii : "allow" ,
181+ schema_tags : "allow" , schema_tags_list : "allow" ,
167182 finops_query_history : "allow" , finops_analyze_credits : "allow" ,
168183 finops_expensive_queries : "allow" , finops_warehouse_advice : "allow" ,
169184 finops_unused_resources : "allow" , finops_role_grants : "allow" ,
170185 finops_role_hierarchy : "allow" , finops_user_roles : "allow" ,
171- schema_detect_pii : "allow" , schema_tags : "allow" , schema_tags_list : "allow" ,
186+ // Core tools
172187 altimate_core_validate : "allow" , altimate_core_check : "allow" ,
173188 altimate_core_rewrite : "allow" ,
174- tool_lookup : "allow" ,
189+ // Read-only file access
175190 read : "allow" , grep : "allow" , glob : "allow" ,
176- question : "allow" , webfetch : "allow" , websearch : "allow" ,
177- training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
178- } ) ,
179- userWithSafety ,
180- ) ,
181- mode : "primary" ,
182- native : true ,
183- } ,
184- executive : {
185- name : "executive" ,
186- description : "Read-only data exploration with output calibrated for non-technical executives. No SQL or jargon — findings expressed as business impact." ,
187- prompt : PROMPT_EXECUTIVE ,
188- options : { audience : "executive" } ,
189- permission : PermissionNext . merge (
190- defaults ,
191- PermissionNext . fromConfig ( {
192- "*" : "deny" ,
193- sql_execute : "allow" , sql_validate : "allow" , sql_analyze : "allow" ,
194- sql_translate : "allow" , sql_optimize : "allow" , lineage_check : "allow" ,
195- warehouse_list : "allow" , warehouse_test : "allow" , warehouse_discover : "allow" ,
196- schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
197- schema_cache_status : "allow" , sql_explain : "allow" , sql_format : "allow" ,
198- sql_fix : "allow" , sql_autocomplete : "allow" , sql_diff : "allow" ,
199- finops_query_history : "allow" , finops_analyze_credits : "allow" ,
200- finops_expensive_queries : "allow" , finops_warehouse_advice : "allow" ,
201- finops_unused_resources : "allow" , finops_role_grants : "allow" ,
202- finops_role_hierarchy : "allow" , finops_user_roles : "allow" ,
203- schema_detect_pii : "allow" , schema_tags : "allow" , schema_tags_list : "allow" ,
204- altimate_core_validate : "allow" , altimate_core_check : "allow" ,
205- altimate_core_rewrite : "allow" ,
206- tool_lookup : "allow" ,
207- read : "allow" , grep : "allow" , glob : "allow" ,
208- question : "allow" , webfetch : "allow" , websearch : "allow" ,
209- training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
210- } ) ,
211- userWithSafety ,
212- ) ,
213- mode : "primary" ,
214- native : true ,
215- } ,
216- validator : {
217- name : "validator" ,
218- description : "Test, lint, and verify data integrity. Cannot modify files." ,
219- prompt : PROMPT_VALIDATOR ,
220- options : { } ,
221- permission : PermissionNext . merge (
222- defaults ,
223- PermissionNext . fromConfig ( {
224- "*" : "deny" ,
225- sql_validate : "allow" , sql_execute : "allow" , sql_analyze : "allow" ,
226- sql_translate : "allow" , sql_optimize : "allow" , lineage_check : "allow" ,
227- warehouse_list : "allow" , warehouse_test : "allow" , warehouse_discover : "allow" ,
228- schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
229- schema_cache_status : "allow" , sql_explain : "allow" , sql_format : "allow" ,
230- sql_fix : "allow" , sql_autocomplete : "allow" , sql_diff : "allow" ,
231- finops_query_history : "allow" , finops_analyze_credits : "allow" ,
232- finops_expensive_queries : "allow" , finops_warehouse_advice : "allow" ,
233- finops_unused_resources : "allow" , finops_role_grants : "allow" ,
234- finops_role_hierarchy : "allow" , finops_user_roles : "allow" ,
235- schema_detect_pii : "allow" , schema_tags : "allow" , schema_tags_list : "allow" ,
236- altimate_core_validate : "allow" , altimate_core_check : "allow" ,
237- altimate_core_rewrite : "allow" ,
238- tool_lookup : "allow" ,
239- read : "allow" , grep : "allow" , glob : "allow" , bash : "allow" ,
240- question : "allow" ,
241- training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
242- } ) ,
243- userWithSafety ,
244- ) ,
245- mode : "primary" ,
246- native : true ,
247- } ,
248- migrator : {
249- name : "migrator" ,
250- description : "Cross-warehouse SQL migration and dialect conversion." ,
251- prompt : PROMPT_MIGRATOR ,
252- options : { } ,
253- permission : PermissionNext . merge (
254- defaults ,
255- PermissionNext . fromConfig ( {
256- sql_execute : "allow" , sql_validate : "allow" , sql_translate : "allow" ,
257- sql_optimize : "allow" , lineage_check : "allow" ,
258- warehouse_list : "allow" , warehouse_test : "allow" ,
259- schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
260- schema_cache_status : "allow" , sql_explain : "allow" , sql_format : "allow" ,
261- sql_fix : "allow" , sql_autocomplete : "allow" , sql_diff : "allow" ,
262- finops_query_history : "allow" , finops_analyze_credits : "allow" ,
263- finops_expensive_queries : "allow" , finops_warehouse_advice : "allow" ,
264- finops_unused_resources : "allow" , finops_role_grants : "allow" ,
265- finops_role_hierarchy : "allow" , finops_user_roles : "allow" ,
266- schema_detect_pii : "allow" , schema_tags : "allow" , schema_tags_list : "allow" ,
267- altimate_core_validate : "allow" , altimate_core_check : "allow" ,
268- altimate_core_rewrite : "allow" ,
269- tool_lookup : "allow" ,
270- read : "allow" , write : "allow" , edit : "allow" ,
271- grep : "allow" , glob : "allow" , question : "allow" ,
272- training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
273- } ) ,
274- userWithSafety ,
275- ) ,
276- mode : "primary" ,
277- native : true ,
278- } ,
279- researcher : {
280- name : "researcher" ,
281- description : "Deep research mode. Thorough multi-step investigation with structured reports. Use for complex analytical questions." ,
282- prompt : PROMPT_RESEARCHER ,
283- options : { } ,
284- permission : PermissionNext . merge (
285- defaults ,
286- PermissionNext . fromConfig ( {
287- "*" : "deny" ,
288- sql_execute : "allow" , sql_validate : "allow" , sql_analyze : "allow" ,
289- sql_translate : "allow" , sql_optimize : "allow" , lineage_check : "allow" ,
290- warehouse_list : "allow" , warehouse_test : "allow" , warehouse_discover : "allow" ,
291- schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
292- schema_cache_status : "allow" , sql_explain : "allow" , sql_format : "allow" ,
293- sql_fix : "allow" , sql_autocomplete : "allow" , sql_diff : "allow" ,
294- finops_query_history : "allow" , finops_analyze_credits : "allow" ,
295- finops_expensive_queries : "allow" , finops_warehouse_advice : "allow" ,
296- finops_unused_resources : "allow" , finops_role_grants : "allow" ,
297- finops_role_hierarchy : "allow" , finops_user_roles : "allow" ,
298- schema_detect_pii : "allow" , schema_tags : "allow" , schema_tags_list : "allow" ,
299- altimate_core_validate : "allow" , altimate_core_check : "allow" ,
300- altimate_core_rewrite : "allow" ,
301- tool_lookup : "allow" ,
302- read : "allow" , grep : "allow" , glob : "allow" , bash : "allow" ,
303- question : "allow" , webfetch : "allow" , websearch : "allow" ,
304- task : "allow" , training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
305- } ) ,
306- userWithSafety ,
307- ) ,
308- mode : "primary" ,
309- native : true ,
310- } ,
311- trainer : {
312- name : "trainer" ,
313- description : "Teach your AI teammate. Scan for patterns, validate training against code, curate knowledge. Read-only." ,
314- prompt : PROMPT_TRAINER ,
315- options : { } ,
316- permission : PermissionNext . merge (
317- defaults ,
318- PermissionNext . fromConfig ( {
319- "*" : "deny" ,
320- read : "allow" , grep : "allow" , glob : "allow" , bash : "allow" ,
321- question : "allow" ,
191+ webfetch : "allow" , websearch : "allow" ,
192+ question : "allow" , tool_lookup : "allow" ,
193+ // Bash: last-match-wins — "*": "deny" MUST come first, then specific allows override
194+ bash : {
195+ "*" : "deny" ,
196+ "ls *" : "allow" , "grep *" : "allow" , "cat *" : "allow" ,
197+ "head *" : "allow" , "tail *" : "allow" , "find *" : "allow" , "wc *" : "allow" ,
198+ "dbt list *" : "allow" , "dbt ls *" : "allow" , "dbt debug *" : "allow" ,
199+ } ,
200+ // Training
322201 training_save : "allow" , training_list : "allow" , training_remove : "allow" ,
323- schema_inspect : "allow" , schema_index : "allow" , schema_search : "allow" ,
324- schema_cache_status : "allow" ,
325- warehouse_list : "allow" , warehouse_discover : "allow" ,
326202 } ) ,
327203 userWithSafety ,
328204 ) ,
@@ -469,7 +345,8 @@ export namespace Agent {
469345 item . name = value . name ?? item . name
470346 item . steps = value . steps ?? item . steps
471347 item . options = mergeDeep ( item . options , value . options ?? { } )
472- item . permission = PermissionNext . merge ( item . permission , PermissionNext . fromConfig ( value . permission ?? { } ) )
348+ // Re-apply safety denials AFTER user config so they cannot be overridden
349+ item . permission = PermissionNext . merge ( item . permission , PermissionNext . fromConfig ( value . permission ?? { } ) , safetyDenials )
473350 }
474351
475352 // Ensure Truncate.GLOB is allowed unless explicitly configured
0 commit comments