62a9c0f0e9
The write_file / patch file tools hard-denied ~/.ssh/config as a "protected system/credential file", while the terminal tool only *asked* for approval on ~/.ssh writes. That inconsistency meant a write to ~/.ssh/config was refused via write_file but succeeded via terminal after an approval prompt -- the same operation flip-flopping between denied and OK depending on which tool ran it. The SSH client config carries no private-key material, and editing it (host aliases, ProxyJump, VS Code Remote-SSH targets) is a routine, user-initiated task. It CAN carry ProxyCommand / Match exec directives that run commands, so a free write is still inappropriate -- approval, not a flat refusal, is the right policy, matching what the terminal tool already does. Changes: - agent/file_safety.py: remove ~/.ssh/config from the flat credential deny; add build_write_approval_paths() + is_write_approval_required(), and short-circuit it out of the ~/.ssh/ prefix deny so the file is allowed at the classifier layer. Private keys, authorized_keys, and everything else under ~/.ssh/ stay hard-denied. - tools/file_tools.py: _check_approval_required_write() routes ssh config writes through the shared _run_approval_gate (once/session/always, honors --yolo, fail-closed with no human), wired into write_file_tool and patch_tool right after the protected-instruction gate. - Non-interactive consumers fail closed: the ACP file bridge (copilot_acp_client) rejects approval-required paths outright, and the TTS output-path picker refuses them as before. - Docs + tests updated (security.md exception note; TestSshConfigApprovalGate covers config approval-gated, keys still hard-denied).