Magent Doctor

Purpose

/doctor and M-x magent-action-run-doctor diagnose Magent, Emacs runtime, and current-project state without giving an LLM general Emacs or shell access. Both entry points execute the same Action and create an isolated Action session under magent-session-directory/actions/doctor.

The M-x entry point immediately displays one read-only Org *Magent Doctor* buffer. The same buffer retains preflight, runtime/package versions, the effective Doctor model route, structured probe tasks, and the final diagnosis. Probe headings move through TODO, DONE, FAIL, or KILL. Probe results are bounded and redacted before analysis; tasks call out only omissions and failures. When a probe reads information already shown in a live Emacs buffer, the task links to that buffer instead of copying its potentially noisy contents. Once the isolated session has been saved, its id is a standard Org link to the read-only Action session viewer, so Org-aware commands such as embark-dwim can follow it.

The buffer retains #+startup: content. Tasks and Diagnosis remain the main top-level sections, while Runtime and Doctor model details live under Environment and Preflight remains available at the end. Preflight opens while confirmation is pending, and Diagnosis opens automatically when the run ends.

Use /doctor select or a prefix argument with the M-x command to review the applicable probe selection. Core runtime diagnostics are always included.

Trust Boundary

Doctor uses two phases:

  1. Trusted, read-only Elisp probes collect bounded structured facts.
  2. One tool-free gptel-request analyzes the sanitized diagnostic bundle.

The provider request has no tools and does not enter the normal Magent agent loop or runtime queue. It may run concurrently with an ordinary conversation, but it does not install its Action session as the user’s current session. /doctor follows the originating runtime session’s effective model route; the M-x entry point falls back to the current gptel defaults. Sampling uses gptel’s streaming path while Doctor exposes only the completed diagnosis. If gptel fails synchronously before contacting the provider, Doctor classifies the failure at this boundary and reports actionable backend configuration guidance without collecting or displaying credential values.

Doctor never intentionally collects a gptel backend object, API keys, auth-source, environment variables, HTTP headers, or raw *gptel-log* content. Absolute paths are normalized to $PROJECT, $HOME, and $TMP. Raw probe return values are not persisted or logged; only bounded, recursively redacted output enters the Action session and provider request.

Redaction is defense in depth, not a sandbox. Custom probes are trusted Emacs Lisp with the same authority as any installed package. They must follow the read-only probe contract, but Magent cannot prevent malicious Elisp from reading or modifying user state. Unsupported or circular probe output fails closed before any provider request is made.

Built-In Probes

  • core-runtime: Magent, gptel, agent-shell, ACP, and Emacs versions; Magent source, mode, session, queue, approvals; and the safe Doctor model-route metadata. It never serializes the provider backend object.
  • current-buffer: buffer metadata without contents.
  • project: project indicators and a read-only Git status when available.
  • diagnostics: existing Flymake, Flycheck, and Eglot state.
  • compilation: bounded tails from existing project compilation buffers.
  • magent-logs: bounded Magent log tail and filtered Magent-related warning and message lines. Raw provider traffic is excluded.
  • source-context: a bounded excerpt around point. This probe is manual-only.

Probes run serially. Ordinary probe errors and timeouts are recorded safely and collection continues. Output validation or redaction failure terminates the entire run without contacting the provider.

Extending Doctor

Register trusted probes with magent-doctor-register-probe:

(require 'magent-action-builtin-doctor)

(magent-doctor-register-probe
 "my-runtime-check"
 :description "Read-only status for my package"
 :predicate (lambda (context)
              (buffer-live-p
               (magent-action-invocation-origin-buffer context)))
 :collector (lambda (_context _state)
              `((feature-loaded . ,(featurep 'my-package))))
 :timeout 2
 :data-categories '(runtime))

Probe ids use lowercase letters, digits, hyphens, or underscores and are at most 64 characters. Collectors must return JSON-safe strings, numbers, booleans, symbols, vectors, lists, plists, alists, or hash tables. Live buffers, processes, backend structs, and circular values are rejected.

For fixed external diagnostics, use magent-doctor-run-process with an executable and argument list. It never invokes a shell and participates in Doctor timeout and cancellation cleanup. Probes must not configure, build, test, edit, or otherwise mutate a project.

Sessions And Cancellation

Use M-x magent-action-list-sessions to inspect results. The viewer shows the final diagnosis first and folds probe activity by default; TAB toggles a section and S-TAB toggles all activity details.

Use M-x magent-action-cancel to cancel an active Doctor request. In the interactive Doctor buffer, C-c C-t on a nonterminal task marks that heading KILL and requests the same whole-Doctor cancellation; it does not skip only that probe. Cancellation terminates an active probe process or aborts the direct gptel request, marks the Action session cancelled, and leaves the user’s current session unchanged. Built-in Elisp probes are short synchronous reads, so task cancellation is normally actionable during an external probe process or provider analysis.

Configuration

The main limits are:

  • magent-doctor-probe-timeout
  • magent-doctor-process-timeout
  • magent-doctor-total-timeout
  • magent-doctor-max-diagnostic-chars
  • magent-doctor-max-probe-chars
  • magent-doctor-source-context-max-chars
  • magent-doctor-log-max-lines

magent-bypass-permission skips the preflight confirmation only. It never disables collection bounds, path normalization, redaction, or the no-tools provider boundary.