Skip to content

Fix silent Copilot MDM hook-install failure#171

Merged
MohamedAklamaash merged 11 commits into
stagingfrom
fix/copilot-mdm-install-failure
Jul 3, 2026
Merged

Fix silent Copilot MDM hook-install failure#171
MohamedAklamaash merged 11 commits into
stagingfrom
fix/copilot-mdm-install-failure

Conversation

@MohamedAklamaash

@MohamedAklamaash MohamedAklamaash commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • GitHub Copilot was the only MDM tool that installed unbound.py per-user by downloading it to a root-owned staging dir and shutil.copyfile-ing it into each home after privilege-drop. The dropped user had to read the staged file; when it couldn't (swallowed chmod widening, or a non-traversable /var/folders temp path on macOS under sudo), the copy failed silently and main() still exited 0 — so the orchestrator (mdm/onboard.py) marked Copilot installed when no hook was written.
  • Root cause fix: read the hook script once as root into memory, then write it as the target user — the only cross-privilege op is now a write into the user's own home (no staged read). This matches how claude-code/codex/cursor already behave and removes a root-owned, world-readable file from disk entirely.
  • Exit-code fix: main() now returns a bool and __main__ exits non-zero when no/partial user install succeeds, so a silent failure can no longer be reported as success.

Changes

  • New modular helpers in copilot/hooks/mdm/setup.py:
    • _fetch_hook_script(gateway_url) — root-only download into an unpredictable mkdtemp dir, read into memory with the gateway URL applied, cleaned up in finally.
    • _apply_gateway_url(text, gateway_url) — pure string rewrite (replaces the old path-based rewrite_gateway_url_in_file).
    • _write_file(path, data, mode)O_NOFOLLOW open + fchmod (umask-proof), reused for both unbound.py and unbound.json.
  • install_hooks_for_user(username, home_dir, script_text) — writes both files via _write_file inside _run_as_user; no more shutil.copyfile from a staged path.
  • Dropped the staging-dir 0o711/0o644 widening (dead once nothing reads the file post-drop).
  • notify_setup_complete is only called on full success, so the backend isn't told setup completed on a failed run.

Test plan

  • New integration tests at the outermost layer (install_hooks_for_user, main()): files actually land + are executable; O_NOFOLLOW refuses a symlinked path; gateway rewrite vs identity; main() returns False / exits non-zero on no-users, partial-failure, and download-failure, and notifies only on success.
  • Full copilot suite green: 26 passed (9 new + 17 existing).
  • Reviewed by elite-pr-reviewer (APPROVE) and /security-review (no High/Critical; net-strengthens the root↔user boundary).

Notes

  • Out of scope (flagged): mdm/onboard.py:89 passes supports_backfill=True for Copilot while the comment at :82-85 says Copilot has no backfill — harmless, left as-is.

🤖 Generated with Claude Code


Note

Medium Risk
Changes MDM install/teardown contracts and exit codes that onboarders rely on; Copilot’s write path is security-sensitive but is a net hardening versus staged root-owned copies.

Overview
Fixes GitHub Copilot MDM installs that could exit 0 with no hooks on disk, and aligns all eight setup.py entrypoints so orchestrators like mdm/onboard.py can treat failures as failures.

Copilot no longer downloads unbound.py to a root-owned staging file and copyfiles it after privilege-drop (which could fail silently when the dropped user could not read the staged path). The script is fetched once as root into memory (_fetch_hook_script), the gateway URL is applied in-process, and each user gets unbound.py / unbound.json written via _write_file (O_NOFOLLOW, fchmod) inside _run_as_user. main() now requires every user home to install successfully; notify_setup_complete and --backfill run only on full success.

Codex hooks gets the same all-users-or-fail success semantics and gates completion notification / backfill on success.

Across augment, claude-code (gateway + hooks), codex (gateway + hooks), cursor, gemini-cli, and copilot: main() / clear_setup() return bool, --clear propagates teardown success, early exits return False, and __main__ ends with sys.exit(0 if ok else 1) (including KeyboardInterrupt → 1). clear_setup() also returns non-zero success when env or managed-artifact teardown partially fails.

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

Greptile Summary

This PR fixes two independent bugs affecting all seven MDM setup.py provisioning scripts. First, every main() function previously exited 0 on early failure (bare return with no explicit exit), so the MDM orchestrator treated every run as successful; all early-failure returns are now return False and __main__ calls sys.exit(0 if ok else 1). Second, Copilot's hook installation staged a root-downloaded unbound.py in a temp directory and then tried to read it after privilege-drop — which could silently fail — leaving unbound.py unwritten while main() still reported success.

  • Copilot root-cause fix (copilot/hooks/mdm/setup.py): _fetch_hook_script downloads as root and reads the script into memory with the gateway URL already applied; install_hooks_for_user receives the str and writes both unbound.py and unbound.json via a new _write_file helper (O_NOFOLLOW + fchmod) running as the target user — no staged read after privilege-drop, no world-readable temp file.
  • Exit-code fix across all scripts: clear_setup() and main() now return bool, all intermediate failures return False, and notify_setup_complete / backfill are gated on full per-user success — partial installs no longer mark the tool as provisioned.
  • Consistency tightening (codex/hooks, copilot): success criterion upgraded from "at least one user installed" to "every enumerated user installed", matching the semantics the orchestrator already expected.

Confidence Score: 5/5

Safe to merge — the copilot hook delivery and the cross-script exit-code changes are correct and address real silent-failure bugs.

The copilot in-memory delivery eliminates the staged-file read-after-privilege-drop race cleanly. Exit-code propagation is implemented consistently across all seven scripts and covers every early-return path. The _write_file fd-transfer guard and the _fetch_hook_script try/finally cleanup are both correct. No pre-existing behaviour is made worse; the one minor cosmetic inconsistency (the "Clear Complete!" banner on partial teardown failure) is pre-existing and does not affect the correctness of the exit code the orchestrator consumes.

No files require special attention. The copilot setup.py has the most logic added and is also the most thoroughly changed; the remaining six files follow an identical, mechanical pattern.

Important Files Changed

Filename Overview
copilot/hooks/mdm/setup.py Core fix: replaces staged-file approach with in-memory script delivery via _fetch_hook_script + _write_file; adds O_NOFOLLOW/fchmod to both files; notify_setup_complete now gated on all-user success.
augment/hooks/mdm/setup.py Exit-code fix: clear_setup() and main() now return bool; all early failures return False; __main__ calls sys.exit(0 if ok else 1).
claude-code/gateway/mdm/setup.py Same exit-code fix pattern as augment: clear_setup() and main() return bool, __main__ exits on the return value.
claude-code/hooks/mdm/setup.py Exit-code fix identical to other hook scripts; no functional changes to the hook installation logic itself.
codex/gateway/mdm/setup.py Exit-code fix; clear_setup() gains teardown_failed tracking including the per-user remove_codex_config_base_url_for_user loop.
codex/hooks/mdm/setup.py Tightens success criterion from "at least one user installed" to "every user installed"; notify_setup_complete and run_backfill are now gated on full success.
cursor/mdm/setup.py Exit-code fix; clear_setup() gains teardown_failed tracking across hooks.json removal, hooks directory removal, and env-var clearing.
gemini-cli/gateway/mdm/setup.py Exit-code fix; clear_setup() gains teardown_failed tracking including Windows-specific settings file/dir removal failures.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant MDM as MDM Orchestrator
    participant main as main() [root]
    participant fetch as _fetch_hook_script()
    participant tmp as Temp Dir (root-owned)
    participant run as _run_as_user(username)
    participant write as _write_file() [as user]
    participant notify as notify_setup_complete()

    MDM->>main: run setup.py --api-key ...
    main->>fetch: _fetch_hook_script(gateway_url)
    fetch->>tmp: mkdtemp() → staging_dir
    fetch->>tmp: download_file(SCRIPT_URL, source_script)
    fetch->>fetch: source_script.read_text() → script_text
    fetch->>tmp: shutil.rmtree(staging_dir) [finally]
    fetch-->>main: script_text: str (in memory)

    loop for each username, home_dir
        main->>run: _run_as_user(username, _install)
        run->>write: _write_file(script_path, script_text, 0o755)
        note over write: O_NOFOLLOW + fchmod — as target user
        run->>write: _write_file(hooks_json, config_json, 0o644)
        write-->>run: success / raises
        run-->>main: True / None
    end

    alt all users installed
        main->>notify: notify_setup_complete(...)
        main-->>MDM: exit 0
    else partial or zero success
        main-->>MDM: exit 1
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant MDM as MDM Orchestrator
    participant main as main() [root]
    participant fetch as _fetch_hook_script()
    participant tmp as Temp Dir (root-owned)
    participant run as _run_as_user(username)
    participant write as _write_file() [as user]
    participant notify as notify_setup_complete()

    MDM->>main: run setup.py --api-key ...
    main->>fetch: _fetch_hook_script(gateway_url)
    fetch->>tmp: mkdtemp() → staging_dir
    fetch->>tmp: download_file(SCRIPT_URL, source_script)
    fetch->>fetch: source_script.read_text() → script_text
    fetch->>tmp: shutil.rmtree(staging_dir) [finally]
    fetch-->>main: script_text: str (in memory)

    loop for each username, home_dir
        main->>run: _run_as_user(username, _install)
        run->>write: _write_file(script_path, script_text, 0o755)
        note over write: O_NOFOLLOW + fchmod — as target user
        run->>write: _write_file(hooks_json, config_json, 0o644)
        write-->>run: success / raises
        run-->>main: True / None
    end

    alt all users installed
        main->>notify: notify_setup_complete(...)
        main-->>MDM: exit 0
    else partial or zero success
        main-->>MDM: exit 1
    end
Loading

Reviews (10): Last reviewed commit: "Gate codex-hooks partial install + make ..." | Re-trigger Greptile

MohamedAklamaash and others added 2 commits June 23, 2026 13:10
Copilot was the only MDM tool installing per-user by downloading unbound.py to
a root-owned staging dir and copyfile-ing it into each home after privilege-drop.
If the dropped user could not read the staged file, the copy failed silently and
main() still exited 0, so the orchestrator marked Copilot installed when no hook
was written.

- Read the hook script once as root and write it as the target user, so the only
  cross-privilege op is a write into the user's own home (no staged read).
- Add modular _fetch_hook_script / _apply_gateway_url / _write_file helpers;
  _write_file uses O_NOFOLLOW + fchmod.
- main() now returns success and exits non-zero when no user gets installed, so
  the MDM orchestrator stops reporting a silent failure as success.
- Add outermost-layer tests for install_hooks_for_user and main() exit semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…y tests

- Only call notify_setup_complete when every user was installed, so the backend
  is not told setup completed on a partial/failed run (exit code already
  reflects this to the orchestrator).
- Add tests: O_NOFOLLOW refuses a symlinked unbound.py path; _apply_gateway_url
  rewrite vs identity; notify is/ isn't called on success vs partial failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MohamedAklamaash MohamedAklamaash requested a review from a team June 23, 2026 07:46
Comment thread copilot/hooks/mdm/setup.py
Comment thread copilot/hooks/mdm/setup.py
Comment thread copilot/hooks/mdm/setup.py Outdated
@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

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


🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head d2c8cc05 · 2026-06-23T07:53Z

… read

- _fetch_hook_script catches a read failure (corrupt/transient) and returns None
  so main() prints the clean download-failed message instead of a raw traceback.
- _install debug_prints the underlying reason before re-raising, so a per-user
  install failure is diagnosable (it is swallowed in the _run_as_user fork).
- _write_file closes the fd if os.fdopen raises before taking ownership.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MohamedAklamaash

Copy link
Copy Markdown
Contributor Author

Addressed all three Greptile P2s in 5d2e870:

  • _fetch_hook_script could raise instead of returning None — now catches a read failure (corrupt/transient), debug_prints the reason, and returns None, so main() prints the clean "Failed to download unbound.py" message (and still exits non-zero) instead of a raw traceback.
  • _write_file fd leak if os.fdopen raises — the fd is now closed before re-raising.
  • Silent failure reason lost in the fork_install now debug_prints the underlying error before re-raising, so a per-user install failure is diagnosable in the MDM debug log (which is always on). This directly supports the motivation for this PR.

All checks green; full copilot suite 26 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

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


🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head e7b2d85c · 2026-06-23T10:32Z

@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 a3e3577f · 2026-06-29T05:11Z

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>
@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 c32e8d2d · 2026-06-29T08:41Z

@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)

Previously acknowledged (not re-flagged)

  • _fetch_hook_script exception path, _write_file fd leak, silent fork failure reason — fixed in 5d2e870 per @MohamedAklamaash; no longer applicable.
  • fchmod-before-write ordering — Greptile/maintainer: no security regression (brief empty-file window only).
  • codex/hooks empty user_homesreturn True — pre-existing reporting inconsistency; out of scope for this PR (PR description).
  • Semgrep pickle / file-permission / subprocess shell=True hits — pre-existing patterns in unchanged code; not introduced by this diff.

🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head d65f9402 · 2026-07-01T13:55Z

@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 high 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 c0ef166. Configure here.

Comment thread copilot/hooks/mdm/setup.py
@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

🛡️ Automated Security Review (consensus)

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

Findings

🔴 Backfill runs after failed hook install

copilot/hooks/mdm/setup.py:1414

  • Impact: When --backfill is set, run_backfill still uploads session data and advances per-user cutoffs even if hook install failed partially or totally — data leaves the device while setup is marked failed, and advanced cutoffs can skip sessions on retry.
  • Fix: Gate backfill on full success: if backfill_mode and success: run_backfill(api_key, base_url, user_homes).
  • Flagged by: Cursor, Claude

🟡 Codex hooks partial install still reports success

codex/hooks/mdm/setup.py:1858

  • Impact: main() returns True and calls notify_setup_complete when some users fail hook install (0 < installed < len(user_homes)); the orchestrator can mark Codex installed on machines where some users have no hook — the same silent-partial-failure class this PR fixes for Copilot.
  • Fix: Mirror Copilot's gate: success = bool(user_homes) and installed == len(user_homes); return success and gate notify_setup_complete on it.
  • Flagged by: Claude

Previously acknowledged (not re-flagged)

  • _fetch_hook_script uncaught read failures — fixed in 5d2e870 (catch, debug_print, return None).
  • _write_file fd leak on os.fdopen failure — fixed in 5d2e870 (os.close(fd) before re-raise).
  • Silent per-user install errors in fork — fixed in 5d2e870 (debug_print of underlying error in _install).
  • mdm/onboard.py supports_backfill=True for Copilot — out of scope / harmless per PR description; left as-is.

🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head c0ef1666 · 2026-07-02T16:05Z

@MohamedAklamaash MohamedAklamaash changed the base branch from main to staging July 3, 2026 06:22
MohamedAklamaash and others added 2 commits July 3, 2026 11:53
Cursor Bugbot (medium): run_backfill ran whenever --backfill was set,
even when hook install failed (success=False). notify_setup_complete is
already gated on success; backfill was not, so a failed setup could still
upload sessions and advance per-user cutoffs — creating a capture gap
since the hooks aren't installed to record going forward. Gate backfill
on success too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

🛡️ Automated Security Review (consensus)

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

Findings

🔴 Backfill runs after failed hook install

copilot/hooks/mdm/setup.py:1418

  • Impact: notify_setup_complete is correctly gated on success, but run_backfill still runs when --backfill is set after partial/zero hook installs; the process exits non-zero yet sessions are uploaded and per-user cutoffs advance, so a later retry can permanently skip audit telemetry.
  • Fix: Gate backfill on full install success — if backfill_mode and success: run_backfill(api_key, base_url, user_homes).
  • Reviewers: Cursor, Claude, Lead

Previously acknowledged (not re-flagged)

  • Codex hooks partial install still succeedscodex/hooks/mdm/setup.py still returns True and notifies on partial per-user failure; pre-existing behaviour intentionally left unchanged by this PR.

🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head f84acc70 · 2026-07-03T06:31Z

@vigneshsubbiah16

Copy link
Copy Markdown
Collaborator

🛡️ Automated Security Review (consensus)

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

Findings

🔴 Codex hooks: partial per-user install still reported as success

codex/hooks/mdm/setup.py:1858

  • Impact: Only zero-user failure exits non-zero; a partial install (e.g. 1 of N users) still returns True, may call notify_setup_complete / run_backfill, and the orchestrator will not retry — leaving some users unmonitored, the same coverage-gap class this PR fixes for Copilot.
  • Fix: Mirror Copilot gating: success = bool(user_homes) and installed == len(user_homes); gate notify_setup_complete, run_backfill, and the return value on success.
  • Flagged by: Claude, Lead reviewer

🟡 --clear reports success without verifying cleanup

copilot/hooks/mdm/setup.py:1311 (same pattern in all 7 other MDM setup.py scripts)

  • Impact: clear_setup(); return True always exits 0 even if teardown fails, so stale hooks, env vars, or API-key material can persist undetected during offboarding.
  • Fix: Have clear_setup() return a bool and propagate it (return clear_setup()).
  • Flagged by: Claude

Previously acknowledged (not re-flagged)

  • Copilot backfill after failed hook install — Fixed in 2838ad0: run_backfill gated on if success and backfill_mode (@MohamedAklamaash).
  • _fetch_hook_script read failures bypassing None guard — Addressed: except Exception logs and returns None (@MohamedAklamaash).
  • _write_file fd leak if os.fdopen raises — Addressed: os.close(fd) in except before re-raise (@MohamedAklamaash).
  • Fork-child install failures losing underlying error — Addressed: _install debug_prints the exception before re-raising (@MohamedAklamaash).

🤖 consensus review · reviewers: Cursor,Claude,Semgrep,Gitleaks · head 2838ad03 · 2026-07-03T06:41Z

Security consensus review (2 findings):

1. codex hooks: a partial per-user install (e.g. 1 of N users) still
   returned True, called notify_setup_complete/run_backfill, and the
   orchestrator would not retry — leaving some users unmonitored. Mirror
   the Copilot gating: success = bool(user_homes) and installed == len,
   and gate notify, backfill, and the return value on success.

2. --clear reported success unconditionally (clear_setup(); return True),
   so a failed teardown still exited 0 and stale hooks/env vars/API-key
   material could persist undetected during offboarding. clear_setup now
   returns a bool (False on admin-denied or any teardown failure) and main
   propagates it. Applied across all 8 MDM setup.py scripts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MohamedAklamaash

Copy link
Copy Markdown
Contributor Author

Both findings addressed in b6b5a0f:

🔴 Codex hooks — partial install reported as success (codex/hooks/mdm/setup.py)
Mirrored the Copilot gating:

success = bool(user_homes) and installed == len(user_homes)
...
print("Setup Complete!" if success else "Setup Failed")
if success:
    notify_setup_complete(...)
if success and backfill_mode:
    run_backfill(...)
return success

A partial per-user install now exits non-zero and skips notify_setup_complete / run_backfill, so the orchestrator retries instead of leaving users unmonitored.

🟡 --clear reported success without verifying cleanup (all 8 MDM setup.py)
clear_setup() now returns a bool and main() propagates it (return clear_setup()):

  • returns False on admin-denied (the privilege guard) and on any teardown failure (a teardown_failed flag set in every "Failed to clear …" branch — env vars, managed hooks/settings, and per-file specifics like cursor's enterprise hooks.json/dir and gemini's Windows settings path);
  • not_found / "nothing to clear" stays a success.
    A failed offboarding teardown now exits non-zero so stale hooks/env vars/API-key material cannot persist undetected.

Verified: all 8 files ast.parse clean; non-root --clear now exits 1 (was 0); in-process test confirms clear_setup()True when nothing/all cleared, False on env-clear failure, managed-clear failure, and admin-denied.

@vigneshsubbiah16 vigneshsubbiah16 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🛡️ 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 b6b5a0f7 · 2026-07-03T07:02Z

@MohamedAklamaash MohamedAklamaash merged commit a956385 into staging Jul 3, 2026
4 checks passed
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.

3 participants