Skip sudo wrapper when os_user matches bot process user#192
Conversation
When claude_user equals the current process user, self-sudo fails because sudoers disallows it. Detect this at spawn time using pwd.getpwuid(os.getuid()).pw_name and skip the sudo wrapper, logging a warning about the misconfiguration. The local effective_claude_user variable avoids mutating the instance attribute, which may be read elsewhere. Fixes #191
Review by KaiPR Review: Skip sudo wrapper when os_user matches bot process userThe logic is sound and solves a real problem cleanly. Three findings: WARNING — Unhandled
|
…eticity - Wrap pwd.getpwuid() in try/except KeyError for container environments where the UID has no /etc/passwd entry (falls through to sudo path) - Move import pwd to module level in test_claude.py - Patch pwd.getpwuid in test_different_user_still_uses_sudo for hermeticity - Add test_pwd_keyerror_falls_through_to_sudo for the new fallback
Review by KaiAll three issues from the prior review have been addressed: One new finding: SUGGESTION —
|
Review by KaiPR Review: Skip sudo wrapper when os_user matches bot process userAll three findings from the first review and the single finding from the second review have been addressed. The One new finding: SUGGESTION — Warning message says
|
Review by KaiPR Review: Skip sudo wrapper when os_user matches bot process userAll findings from the three prior review rounds have been addressed in this diff:
No new findings. The implementation is clean:
Ready to merge. |
Review by KaiPR Review: Skip sudo wrapper when os_user matches bot process userAll findings from the four prior review rounds have been addressed in this diff. A fresh pass finds nothing new. Implementation (
Tests (
No new findings. Ready to merge. |
PR #192 added a self-sudo check to claude.py but missed the identical sudo pattern in triage.py and review.py. In single-user deployments where claude_user matches the bot process user, triage and review subprocesses attempted self-sudo and silently failed. Move the check into config.resolve_claude_user() and apply it in all three locations. Both the spawn path (sudo -u prefix) and cleanup path (killpg vs proc.kill) use the resolved value so they stay in sync. Fixes #194
* Extract self-sudo skip into shared resolve_claude_user() utility PR #192 added a self-sudo check to claude.py but missed the identical sudo pattern in triage.py and review.py. In single-user deployments where claude_user matches the bot process user, triage and review subprocesses attempted self-sudo and silently failed. Move the check into config.resolve_claude_user() and apply it in all three locations. Both the spawn path (sudo -u prefix) and cleanup path (killpg vs proc.kill) use the resolved value so they stay in sync. Fixes #194 * Fix review: remove duplicate log, use module-scoped patches, match timeout pattern * Make test_different_user_returns_unchanged hermetic with monkeypatch
Summary
When
os_user(fromusers.yaml) orCLAUDE_USERmatches the user the bot process is already running as, skip thesudo -uwrapper instead of crashing with "Claude process EOF."The problem
_ensure_started()unconditionally wraps the Claude command withsudo -u <user>whenclaude_useris set. Self-sudo (sudo -u kaiwhen already running askai) fails because sudoers disallows it, and the subprocess dies immediately.The fix
Compare
self.claude_useragainstpwd.getpwuid(os.getuid()).pw_nameat spawn time. If they match, treat it as ifclaude_userwere None (no sudo, no process group, no PGID). Log a warning so the misconfiguration is visible.Changes
import pwdeffective_claude_userlocalself.claude_userpwd.getpwuid(os.getuid()).pw_namecomparisonstart_new_session,_pgid, log message useeffective_claude_userTest plan
test_self_sudo_skipped- same user skips sudo, no process group, warning loggedtest_different_user_still_uses_sudo- different user still gets sudo wrappermake checkcleanFixes #191