spfcraze
48e8254567
perf(tools): use load_config_readonly on the approval guard path
...
The terminal-command guard path loaded config 2-3x per invocation via
load_config(), which pays a defensive deepcopy of the entire config on
every call (~356us of the ~376us warm-cache cost measured on a real
config.yaml). All six swapped call sites were audited read-only — every
caller takes scalar reads or iterates the returned structures; none
mutate (the save path at save_permanent_allowlist keeps load_config) —
so they now use load_config_readonly(), the API built for exactly this
(precedent: #74211 , #74322 ; the one unsafe-site lesson from #56085 's
salvage is covered by the mutation audit and a cache-integrity test).
Measured (real config.yaml, warm cache): load_config 376.0us ->
load_config_readonly 19.9us (18.9x); full guard pass
check_all_command_guards('ls -la','local') 930.7us -> 241.8us (3.85x).
Tests: new test_approval_config_readonly.py drives the real functions
against a temp HERMES_HOME — readonly call counts per function, a
no-deepcopy pin for the full guard pass, and cache-identity/integrity
checks. Existing test mocks retargeted from load_config to
load_config_readonly (same injection intent). Note: 6
test_approval_mode_parity failures are pre-existing ordering flakes —
identical with the change stashed on clean main.
2026-08-02 21:17:49 +05:30
..
2026-05-19 17:27:24 -07:00
2026-06-19 11:37:51 -07:00
2026-07-31 22:31:22 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:24:14 -07:00
2026-07-29 13:10:23 -07:00
2026-06-27 21:07:53 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-06-28 00:57:42 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 14:27:12 +05:30
2026-07-27 11:53:48 -04:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:28:15 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 21:17:49 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-05-28 22:26:25 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-05-28 22:26:25 -07:00
2026-05-20 11:44:10 -07:00
2026-07-29 15:24:14 -07:00
2026-07-29 13:10:23 -07:00
2026-06-27 19:23:15 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-02 04:51:56 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-05-29 19:23:05 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-26 20:59:21 -07:00
2026-07-29 13:10:23 -07:00
2026-06-27 04:39:26 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 11:40:59 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:18:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-05 13:42:46 -07:00
2026-05-28 22:26:25 -07:00
2026-07-29 15:37:24 -07:00
2026-05-28 22:26:25 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:21:26 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 21:52:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:21:26 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-01 05:06:00 -07:00
2026-07-28 19:06:59 +05:30
2026-07-29 15:24:14 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-20 02:25:57 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 16:44:12 -07:00
2026-07-29 19:48:37 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 19:48:37 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 22:33:03 -07:00
2026-07-31 22:53:20 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 14:27:12 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-18 19:55:16 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-18 21:20:48 -04:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-11 03:44:02 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-05-27 05:43:20 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-06-10 12:39:44 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 11:40:59 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-08-01 16:42:57 -07:00
2026-07-29 13:10:23 -07:00
2026-05-19 20:49:11 +01:00
2026-07-29 15:24:14 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00