Skip to content

Propagate MDM setup failures via exit code across all tools#187

Closed
MohamedAklamaash wants to merge 1 commit into
mainfrom
fix/mdm-scripts-sync
Closed

Propagate MDM setup failures via exit code across all tools#187
MohamedAklamaash wants to merge 1 commit into
mainfrom
fix/mdm-scripts-sync

Conversation

@MohamedAklamaash

@MohamedAklamaash MohamedAklamaash commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What

Follow-up to #171 (review request: "keep other tools' MDM scripts in sync"). Ports the exit-code contract from the copilot fix to every other tool's MDM setup.py.

Why

mdm/onboard.py gates each tool's success on the subprocess returncode. But in every other tool's setup.py:

  • main() used bare return (→ None) on all error paths, and
  • __main__ called main() then exited 0 unless an exception was raised.

So any mid-run failure — missing root, MDM key fetch, env-var write, hook/managed-settings config — silently reported success to the orchestrator. This is the same silent-failure class that caused the original copilot symptom (tool "installed" per the orchestrator, but artifacts missing on the machine).

Change (uniform across all 7)

  • main() returns True on success / --clear, False on every error path.
  • __main__ captures the result and sys.exit(1) on KeyboardInterrupt, on exception, or when main() is falsy; sys.exit(0) only on real success.

Files: augment/hooks, claude-code/{gateway,hooks}, codex/{gateway,hooks}, cursor, gemini-cli/gateway.

Scope / what's intentionally NOT ported

The copilot-specific per-user read-as-root / write-as-user refactor (_fetch_hook_script, _write_file) is not carried over. Those tools download the hook script as the dropped target user directly into the user's own home, so they never had copilot's cross-privilege read failure. Only the exit-code contract is broadly applicable.

Verification

  • python3 -m py_compile passes on all 7 files.
  • Confirmed no bare return remains in any main() body.
  • No new comments added; changes are limited to return statements and the __main__ block.

🤖 Generated with Claude Code


Note

Low Risk
Behavior-only change to process exit codes; no install logic or security paths modified.

Overview
Aligns seven MDM setup.py scripts (Augment, Claude gateway/hooks, Codex gateway/hooks, Cursor, Gemini gateway) with the subprocess contract that mdm/onboard.py already uses: success only when returncode == 0.

main() now returns True on success and on --clear, and False on every validation/setup failure path (missing admin, bad args, MDM key fetch, env writes, hook/managed-settings config, etc.) instead of bare return (None).

The __main__ block captures that result and calls sys.exit(0 if ok else 1), with sys.exit(1) on KeyboardInterrupt and exceptions (replacing exit(1) where applicable).

This stops mid-run failures from exiting 0 and being reported as installed when artifacts were never applied—the same silent-failure class as the earlier Copilot fix.

Reviewed by Cursor Bugbot for commit 98cb63a. Bugbot is set up for automated code reviews on this repo. Configure here.

Greptile Summary

This PR makes MDM setup scripts report failures through process exit codes. The main changes are:

  • Explicit True and False returns from setup main() functions.
  • Nonzero exits for setup errors, exceptions, and interrupts.
  • Mirrored exit-code handling across the affected tool setup scripts.

Confidence Score: 4/5

The setup failure paths mostly behave correctly, but the clear path can still report success after failed cleanup.

  • Setup errors now return failure instead of falling through.
  • The new entrypoint uses available sys imports and explicit boolean results.
  • --clear returns success without checking whether cleanup actually completed.

The mirrored --clear branches in the changed MDM setup scripts.

Important Files Changed

Filename Overview
augment/hooks/mdm/setup.py Adds boolean return handling for setup success and failure; the clear path can still mask cleanup failure.
claude-code/gateway/mdm/setup.py Adds explicit setup success and failure returns with the same unconditional clear success pattern.
claude-code/hooks/mdm/setup.py Adds explicit setup success and failure returns with mirrored exit-code handling.
codex/gateway/mdm/setup.py Adds explicit setup failure returns for missing inputs, environment writes, and user configuration failures.
codex/hooks/mdm/setup.py Adds explicit setup failure returns for hook setup and related error paths.
cursor/mdm/setup.py Adds explicit setup failure returns and process exit handling for Cursor MDM setup.
gemini-cli/gateway/mdm/setup.py Adds explicit setup failure returns for key fetches, environment writes, and gateway setup.

Reviews (1): Last reviewed commit: "Propagate MDM setup failures via exit co..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

The MDM orchestrator (mdm/onboard.py) gates each tool's success on the
subprocess returncode. Every tool's setup.py main() returned None on its
error paths and __main__ exited 0 unless an exception was raised, so any
mid-run failure (missing privileges, MDM key fetch, env var write, hook
config) reported success to the orchestrator.

This mirrors the exit-code contract landed for copilot in #171:
- main() returns True on success / clear, False on every error path
- __main__ captures the result and exits 1 on KeyboardInterrupt, on
  exception, or when main() returns falsy; 0 only on real success

Applied to augment, claude-code (gateway + hooks), codex (gateway +
hooks), cursor, and gemini-cli. The copilot per-user read-as-root/
write-as-user refactor is not ported: those tools download the hook
script as the dropped target user into the user's own home, so they
never had copilot's cross-privilege read failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MohamedAklamaash MohamedAklamaash requested a review from a team June 29, 2026 08:16

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 98cb63a. Configure here.

if clear_mode:
clear_setup()
return
return True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear mode false success

High Severity

In --clear mode, main() always returns True right after clear_setup(), even when clear_setup() exits early (for example missing root/admin) without performing cleanup. The new __main__ block then exits 0, so mdm/onboard.py treats a failed uninstall as success.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 98cb63a. Configure here.

Comment on lines 1254 to +1255
clear_setup()
return
return True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Clear Failure Exits Successfully

When --clear runs without root or a cleanup step only prints a failure, clear_setup() returns without raising and this branch still returns True. The new sys.exit(0 if ok else 1) path then reports success to the MDM orchestrator even though cleanup did not happen or only partially completed.

@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

🛡️ Automated Security Review (consensus)

0 findings — 0 high-confidence, 0 to triage. Reviewers: Cursor, Claude, Semgrep, Gitleaks.

✅ Security consensus: no issues found. (reviewers: Cursor, Claude, Semgrep, Gitleaks)


🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head 98cb63ae · 2026-06-29T08:21Z

@MohamedAklamaash

Copy link
Copy Markdown
Contributor Author

Folding these changes into #171 instead, per review request to keep the MDM sync in the same PR. Pushed as c32e8d2 on fix/copilot-mdm-install-failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants