Skip to main content

axm-doctor

Env bootstrap + auth-status doctor (detect, propose, orchestrate)

axm-audit axm-init Coverage Python 3.12+


Overview

Env bootstrap + auth-status doctor (detect, propose, orchestrate)

Features

  • ✅ Bootstrap-safe detection — importing axm_doctor (or axm_doctor.detect) pulls no AXM package: detect.py defers its AXM imports and the package re-exports lazily (PEP 562). detect_tool remains a stdlib + pydantic probe. On each detect_auth call, the credential catalog is discovered lazily; if it is unavailable, detection safely degrades to binary presence.
  • ✅ Config-resolvability checks — detect_git_identity reports whether a git committer identity is resolvable (a truthy [git].default in the axm-config store, else the exit code of git config --get user.email) and detect_gh_config reports whether gh carries a base config (gh config get git_protocol exit code; not_installed when gh is absent). Value-free like auth: only the store presence and exit codes are inspected, never the identity/config value. Both degrade to unconfigured on any error instead of raising. The env_doctor tool surfaces them under a config key ({git: {state}, gh: {state}}).
  • ✅ Declaration-driven, read-only auth — each package that drives a third-party tool declares how to probe it and owns every tool-specific path, service name and recovery command. detect_auth only translates the declaration outcomes into logged_in, logged_out or not_installed; it never reads or returns authentication material. AuthStatus.declaration_consulted is True when such a declaration was found and consulted, including when its probe could not conclude. Without a declaration, the flag is False: an installed binary yields undetermined because its session cannot be verified, while an absent binary yields not_installed.
  • ✅ Frozen result models — ToolStatus, AuthStatus, GitIdentityStatus and GhConfigStatus are immutable pydantic models; authentication results contain state metadata, never a token.
  • ✅ Install plans, never silent installs — install_command proposes the official install command for a known tool (uv, claude, codex) without running anything; run_install is a dry-run by default (confirm=False) that only echoes the command it would run. It installs strictly when the caller opts in with confirm=True, then re-detects the tool via detect_tool.
  • ✅ Kind-aware, value-free provenance — collect_credential_provenance reports each declaration with its coordinate, declared kind, serving layer/state, and presence flag. Credential kinds (for example token) and auth_dependency coexist in one report; a failing declaration is isolated as unknown / absent without erasing healthy peer verdicts.
  • ✅ Orchestrates, never possesses — missing_secrets reads the axm-vault catalog and value-free resolver provenance to list credential specs that resolve to missing; auth_dependency declarations are excluded because an OAuth/session dependency is not a secret to provision. A MissingSecret can identify the account concerned with instance or signal that a multi-instance group declares no account yet with awaiting_instance; account lookups use only axm-vault's exact canonical coordinate, so a served sibling cannot hide a starving account. provision_missing is a dry-run by default (confirm=False) that returns only credential groups it would prompt for; on confirm=True it delegates to vault's run_setup(only=…). The secret value never transits axm-doctor — every write goes through vault's API.
from axm_doctor import detect_tool, detect_auth
from axm_doctor.detect import detect_git_identity, detect_gh_config

detect_tool("uv")      # ToolStatus(name='uv', state='present', version='0.5.1', path=...)
detect_auth("gh")      # declaration -> AuthStatus(state='logged_in', declaration_consulted=True, ...)
detect_auth("unknown") # PATH fallback -> AuthStatus(..., declaration_consulted=False)
detect_git_identity()  # GitIdentityStatus(state='configured')  — store [git].default or `git config user.email`
detect_gh_config()     # GhConfigStatus(state='configured')     — `gh config get git_protocol`
from axm_doctor import install_command, run_install

plan = install_command("uv")          # InstallPlan(tool='uv', human_command='curl -LsSf https://astral.sh/uv/install.sh | sh', ...)
install_command("bogus")              # None — never guesses a command

run_install(plan)                     # dry-run (confirm=False): executed=False, nothing installed, command echoed
run_install(plan, confirm=True)       # installs, then re-detects: InstallResult(executed=True, returncode=0, post_check=ToolStatus(...))
from axm_doctor import missing_secrets, provision_missing

missing_secrets()                     # MissingSecret rows; instance identifies the account when known
                                      # awaiting_instance=True means a multi group declares no account yet
                                      # [] when the vault catalog is empty — never reads a secret value

provision_missing()                   # dry-run (confirm=False): ProvisionResult(provisioned=False, groups=['research.fred']) — the groups it WOULD prompt for
provision_missing(confirm=True)       # delegates to vault's run_setup(only=...); doctor never stores a secret itself
                                      # in a non-interactive shell (no TTY) it provisions nothing: ProvisionResult(provisioned=False, reason=...)

CLI

The axm-doctor console script has two commands:

axm-doctor check       # read-only report (tools + auth + provenance by kind + missing credentials)
axm-doctor bootstrap   # interactive repair: installs absent tools / runs vault setup only on an explicit "y"

The same read-only surface is exposed as the env_doctor and auth_status axm.tools (MCP + axm <tool> CLI + DAG node). In the per-tool auth map, auth_status publishes {state, login_cmd, declaration_consulted}; its text adds [no declaration] only when no discovered declaration covered that tool. The credential report keeps its value-free {layer, present} shape and groups provenance by declared kind; no token value is ever serialized.

Installation

uv add axm-doctor

Or as a workspace dependency in pyproject.toml:

[project]
dependencies = ["axm-doctor"]

[tool.uv.sources]
axm-doctor = { workspace = true }

Development

This package is part of the axm-forge uv workspace.

# Run this package's tests (from the workspace root)
uv run --package axm-doctor pytest packages/axm-doctor

# Lint + type-check + tests for the whole workspace
make check

License

Apache-2.0 — © 2026 Gabriel Jarry

Metadata

Release files for axm-doctor 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for axm-doctor 0.1.0
File Size Uploaded
axm_doctor-0.1.0.tar.gz 50.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for axm-doctor 0.1.0
File Interpreter ABI Platform
axm_doctor-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 76.8 kB

Release files / axm_doctor-0.1.0.tar.gz

Download URL axm_doctor-0.1.0.tar.gz
Size 50.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6f990fc9cc11b2a444db6de965d5b12c1bd35d08821fb38b95d19147cd1aeaf9
BLAKE2b-256 checksum
How to use checksums
dc0392346644bc6614cb63150de1bae48ccc1955e5792f2a12f7933e90648445
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release files / axm_doctor-0.1.0-py3-none-any.whl

Download URL axm_doctor-0.1.0-py3-none-any.whl
Size 26.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0735f87e4d1e2c07dbe3e914fdedfba5feeb210c7077f8983dc90245b96f57f1
BLAKE2b-256 checksum
How to use checksums
e40e277124424084bf240f45a1e88818605475686e8a4118ea18320808203198
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page