Python API
All entry points below are exported from axm_doctor. Directives target defining modules so lazy exports remain statically resolvable. Start with the verified narrative contracts, which qualify broader claims in implementation docstrings.
Detection
detect
Stdlib-only detection of external tools and third-party auth state.
Tool/auth probing (:func:detect_tool, :func:detect_auth) depends on the
standard library and pydantic only — no AXM package is imported at module
load, so this layer runs as the bootstrap probe before the rest of AXM is
installable. The git-identity check (:func:detect_git_identity) additionally
resolves the central axm-config store ([git].default) to know whether a
committer identity exists; that import is deferred to the function body so the
module stays importable on a machine where axm-config is not yet present.
The value is never read, only its presence. All detection is strictly
read-only: it inspects an exit code or the existence of a credential/store
entry, and never reads the token or identity value.
ToolState = Literal['present', 'absent']
AuthState = Literal['logged_in', 'logged_out', 'not_installed', 'undetermined']
GitIdentityState = Literal['configured', 'unconfigured']
GhConfigState = Literal['configured', 'unconfigured', 'not_installed']
ToolStatus
Bases: BaseModel
Frozen result of probing a single external tool on PATH.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
AuthStatus
Bases: BaseModel
Frozen read-only auth state for a third-party binary.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
GitIdentityStatus
Bases: BaseModel
Frozen verdict on whether a git committer identity is resolvable.
state is decided from the presence of a [git].default store entry
or the exit code of git config --get user.email — the identity value
itself is never read.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
GhConfigStatus
Bases: BaseModel
Frozen verdict on whether gh carries a base configuration.
configured when gh config get git_protocol exits 0, unconfigured
otherwise, not_installed when the gh binary is absent. The config
value itself is never read.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
detect_tool(name)
Probe name on PATH and parse <name> --version.
Returns present with the parsed version string when found, absent
otherwise. Never raises on a missing or misbehaving tool.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
detect_auth(tool)
Report auth state through a package declaration when one is installed.
A tool without a declaration degrades to presence detection: an installed binary has an undetermined auth state because its session cannot be verified.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
detect_git_identity()
Report whether a git committer identity is resolvable, value-free.
Cheapest source first: a truthy [git].default in the axm-config
store means an identity exists. Otherwise fall back to the exit code of
git config --get user.email (its stdout — the email — is captured and
discarded, never returned). Any missing binary / OSError /
SubprocessError degrades to unconfigured without raising.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
detect_gh_config()
Report whether gh carries a base config, value-free.
Probes the exit code of gh config get git_protocol (its stdout is
captured and discarded). gh absent → not_installed; any
OSError / SubprocessError degrades to unconfigured. This is
distinct from and additional to the gh auth status login check.
Source code in packages/axm-doctor/src/axm_doctor/detect.py
Provenance
credentials
Value-free credential provenance collected from axm-vault.
CredentialProvenance
Bases: BaseModel
The serving layer and presence of one credential coordinate.
Source code in packages/axm-doctor/src/axm_doctor/credentials.py
collect_credential_provenance(*, probe=None)
Translate vault provenance into typed rows without carrying values.
Source code in packages/axm-doctor/src/axm_doctor/credentials.py
Installation
install
Install plans: propose an official install command, run only on confirm.
This module NEVER installs silently. install_command only describes the
official command for a known tool; run_install executes it strictly when
the caller opts in with confirm=True. The default path is a dry-run that
echoes the command it would run — honouring the
no-system-install-without-authorization posture.
InstallPlan
Bases: BaseModel
A proposed install command for a single tool — description only.
Building a plan runs nothing. argv is the program + arguments executed
as a bare exec (NO shell). fetch_url, when set, marks a script-installer
plan (e.g. the uv curl | sh recipe): instead of a shell pipe, the script
is downloaded to a temp file and run as sh <tmpfile> — both steps are
argv execs, never shell=True. human_command is the copy-pasteable
form a human would type.
Source code in packages/axm-doctor/src/axm_doctor/install.py
InstallResult
Bases: BaseModel
Outcome of :func:run_install.
On a dry-run (confirm=False) executed is False, returncode is
None, and post_check is None — nothing was installed, so nothing is
re-detected. On a confirmed run, post_check carries the re-detected
:class:~axm_doctor.detect.ToolStatus.
Source code in packages/axm-doctor/src/axm_doctor/install.py
install_command(tool)
Return the official :class:InstallPlan for tool, or None.
Runs nothing. An unknown tool returns None rather than guessing a command.
Source code in packages/axm-doctor/src/axm_doctor/install.py
run_install(plan, *, confirm=False)
Execute plan only when confirm is True; otherwise dry-run.
With the default confirm=False this NEVER installs: it returns the
command it would run with executed=False and returncode=None.
With confirm=True it runs the command, then re-detects the tool via
:func:~axm_doctor.detect.detect_tool and reports the post-install state.
Source code in packages/axm-doctor/src/axm_doctor/install.py
Provisioning
orchestrate
Orchestrate missing-secret detection on top of axm-vault.
This module ORCHESTRATES; it never POSSESSES a secret. :func:missing_secrets
reads the vault catalog (:func:axm_vault.load_catalog) and the value-free
resolver provenance (:func:axm_vault.doctor.doctor_data) to surface the specs
that resolve to "missing" — without ever reading a secret value.
:func:provision_missing delegates to vault's :func:axm_vault.setup.run_setup
only on confirmation; doctor never writes a secret itself (every write goes
through vault's API — the SRP invariant).
Unlike :mod:axm_doctor.detect (bootstrap-sensitive, no AXM import), this is
the orchestration seam, so it depends on axm-vault directly.
MissingSecret
Bases: BaseModel
A credential spec that resolves to "missing" across every layer.
Value-less by construction: it carries only the coordinates of the spec
and a copy-pasteable recovery hint (setup_hint). required
preserves the catalog distinction between indispensable and optional
credentials (the catalog default is True). instance identifies
the account concerned, while awaiting_instance marks a multi-instance
group that declares no account yet. The secret value itself NEVER transits
axm_doctor.
Source code in packages/axm-doctor/src/axm_doctor/orchestrate.py
ProvisionResult
Bases: BaseModel
Outcome of :func:provision_missing.
On a dry-run (confirm=False) provisioned is False and groups
lists the groups it WOULD prompt for. On a confirmed run provisioned
is True ONLY when a post-setup re-scan confirms every previously-missing
spec now resolves — delegating to vault's setup driver is not proof the
user actually supplied the secrets (they may skip/empty the prompts).
still_missing lists the specs that remain unresolved after the run
(always empty on a dry-run), so a partial provisioning is reported truthfully
rather than as a false green.
Source code in packages/axm-doctor/src/axm_doctor/orchestrate.py
missing_secrets()
Return the catalog specs that resolve to "missing", value-free.
Reads the vault catalog and the value-free provenance report; a spec is
reported when no resolver layer supplies it. An empty catalog (the
nominal state for vault today) yields [] gracefully.
Source code in packages/axm-doctor/src/axm_doctor/orchestrate.py
provision_missing(*, confirm=False)
Plan (and on confirm execute) provisioning of missing secrets.
Collects the distinct groups owning at least one missing spec. With
confirm=False it returns the plan without prompting or storing. With
confirm=True it delegates to vault's :func:run_setup (one call per
group, restricted via only=); doctor never stores a secret itself.
Source code in packages/axm-doctor/src/axm_doctor/orchestrate.py
Tools
tools
AXM tools for the doctor — env_doctor and auth_status.
Both are deterministic :class:~axm.tools.base.AXMTool implementations, so
they are reachable over MCP, the axm CLI and as DAG nodes from a single
axm.tools entry-point declaration. They are strictly read-only: they
wrap the central detect/orchestrate functions and never install anything.
They uphold the doctor's security invariant — mirror of vault_doctor —
no tool ever serializes a token value. auth_status reports only the
state and the recovery command (login_cmd); the credential value itself
never transits axm_doctor.
EnvDoctorTool
Read-only env report: tool presence/version + auth + missing secrets.
Source code in packages/axm-doctor/src/axm_doctor/tools.py
name
property
Unique tool identifier.
execute()
Return the full env report; any error becomes a failure ToolResult.
Source code in packages/axm-doctor/src/axm_doctor/tools.py
AuthStatusTool
Report third-party auth state — never a token value (mirror of vault).
Source code in packages/axm-doctor/src/axm_doctor/tools.py
name
property
Unique tool identifier.
execute()
Return value-free auth state; any error becomes a failure ToolResult.