Gate preflight on mm doctor for auth + init readiness#18
Merged
chaitanyapotti merged 4 commits intoJun 22, 2026
Conversation
Make `mm doctor` the single readiness gate before any CLI operation, requiring both `authenticated: true` and `initialized: true` before proceeding. Previously the preflight only checked authentication (`mm auth status`), so an authenticated-but-uninitialized session would pass and then fail at runtime with `NOT_INITIALIZED`. Because doctor's hints are sequential (the init hint is gated on being authenticated), call out that fixing login is not a green light and the agent must re-run `mm doctor` after each remediation until clean. Also align onboarding.md to use `mm doctor` for the init check and readiness verification instead of `mm init show` (which itself throws `NOT_INITIALIZED` when uninitialized) and `mm auth status` (which does not reflect initialization). Co-authored-by: Cursor <cursoragent@cursor.com>
The closing paragraph restated the hard gate and re-run-after-remediation instructions already stated above it. Remove it to keep the gate concise. Co-authored-by: Cursor <cursoragent@cursor.com>
The mm doctor instruction is sufficient; the extra mm init show warning was unnecessary detail for the onboarding step. Co-authored-by: Cursor <cursoragent@cursor.com>
Minor version bump for the mm doctor readiness gate change. cliVersion stays 2.0.0 (no CLI change); per repo convention, skill content changes within the same CLI major get a minor bump. Co-authored-by: Cursor <cursoragent@cursor.com>
chaitanyapotti
approved these changes
Jun 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mm doctorthe single readiness gate in themetamask-agent-walletskill preflight, requiring bothauthenticated: trueandinitialized: truebefore any CLI operation runs.mm auth status). An authenticated-but-uninitialized session passed the gate and then failed at runtime with a thrownNOT_INITIALIZEDerror ("Project not initialized.") on the first command that needed a wallet. Authentication and initialization are independent gates — a session can be authenticated while no wallet mode is selected.mm doctor's hints are sequential, not simultaneous. When not authenticated, doctor emits only the login hint and stays silent about initialization (the init hint is gated onauthenticated && !initialized). So fixing login is not a green light — the agent must re-runmm doctorafter each remediation and loop until the result is clean.workflows/onboarding.mdto the same gate.Why the existing checks were insufficient (they threw instead of reporting)
The prior setup didn't just miss the init gate — its checks surfaced as thrown errors rather than inspectable state:
mm auth statusin the preflight, an authenticated-but-uninitialized session sailed through and then hit a thrownNOT_INITIALIZED("Project not initialized." / hint "Runmm initto set up wallet and trading modes.") mid-operation. The user experiences an error in the middle of, say, a swap instead of being gated up front.workflows/onboarding.mdusedmm init showto detect whether the project was initialized — butmm init showinheritsrequiresInit = true, so on an uninitialized project it throwsNOT_INITIALIZEDrather than reporting state. Using a throwing command as a boolean check is fragile and confusing.mm auth statuscarries no init field, so it can't confirm readiness on its own.mm doctor(requiresAuth = false,requiresInit = false) is purpose-built for this: it returnsauthenticated+initializedbooleans plushintsand never throws on a not-ready session — so it can be used as a clean gate.Prior art / inspiration
This mirrors how single-gate agent skills enforce setup inline with a hard "do not proceed" instruction. See Stripe's Link CLI skill, which puts its one setup gate (authentication) directly in the always-read SKILL.md with an explicit
DO NOT PROCEED until the user is authenticatedline: https://raw.githubusercontent.com/stripe/link-cli/refs/heads/main/skills/create-payment-credential/SKILL.mdMetaMask has a two-gate setup (login and
mm init); this PR brings the second gate up to the same "block until ready" standard.Verification
Wording was checked against the CLI source (
@metamask/agentic-cliv2.0.0):CommandError("NOT_INITIALIZED", "Project not initialized.", "Run \mm init` to set up wallet and trading modes.")inruntime/Command.ts`.DoctorCommand.#isInitialized: a wallet mode must be set, and forserver-walleta trading mode too (byokneeds only the wallet mode).mm doctorhasrequiresAuth = false/requiresInit = falseand returnsauthenticated+initializedbooleans plushints; the init hint is gated onauthenticated && !initialized.mm init showinheritsrequiresInit = true, so it throwsNOT_INITIALIZEDon an uninitialized project rather than reporting state.mm auth statusreturns no initialization field.Before/after validation (A/B test)
Ran two fresh agents against an identical CLI state — authenticated but not initialized (a real
uatsession with the wallet/trading mode cleared) — each told to follow a skill and accomplish "check the wallet balance". Only the skill differed.main)mm --version→mm auth statusmm --version→mm doctorauth statusreportedauthenticated: true, treated as "go"mm doctorreportedinitialized: false+ hintmm wallet balance?NOT_INITIALIZEDruntime errormm init; no errorThe old-skill agent diagnosed the gap itself: "Being authenticated is necessary but not sufficient… the prescribed preflight flow never tells you to run [an init check]… so it walked me straight into NOT_INITIALIZED."
Happy-path check (prod, already authenticated + initialized): the new skill resolves in the same 3 commands (
--version→doctor→wallet balance) with no redundant calls, so the gate adds no friction when the session is already ready.Caveat: single run per scenario, one model, and the agents were instructed to follow the named skill (compliance bias). The before/after contrast is nonetheless stark and reproduces the documented failure.
Test plan
mm doctorreportsauthenticated: falseand the login hint only.mm doctorreportsauthenticated: true,initialized: false, and the "Authenticated but not initialized" hint.mm init:mm doctorreportsinitialized: truewith no blocking hints.