Skip to content

Gate preflight on mm doctor for auth + init readiness#18

Merged
chaitanyapotti merged 4 commits into
MetaMask:mainfrom
cloudonshore:add-init-preflight-gate
Jun 22, 2026
Merged

Gate preflight on mm doctor for auth + init readiness#18
chaitanyapotti merged 4 commits into
MetaMask:mainfrom
cloudonshore:add-init-preflight-gate

Conversation

@cloudonshore

@cloudonshore cloudonshore commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Make mm doctor the single readiness gate in the metamask-agent-wallet skill preflight, requiring both authenticated: true and initialized: true before any CLI operation runs.
  • Previously the preflight only checked authentication (mm auth status). An authenticated-but-uninitialized session passed the gate and then failed at runtime with a thrown NOT_INITIALIZED error ("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.
  • Call out a subtle trap: 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 on authenticated && !initialized). So fixing login is not a green light — the agent must re-run mm doctor after each remediation and loop until the result is clean.
  • Align workflows/onboarding.md to 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:

  1. Runtime guard, not a preflight. With only mm auth status in the preflight, an authenticated-but-uninitialized session sailed through and then hit a thrown NOT_INITIALIZED ("Project not initialized." / hint "Run mm init to 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.
  2. The init check itself threw. workflows/onboarding.md used mm init show to detect whether the project was initialized — but mm init show inherits requiresInit = true, so on an uninitialized project it throws NOT_INITIALIZED rather than reporting state. Using a throwing command as a boolean check is fragile and confusing.
  3. mm auth status carries no init field, so it can't confirm readiness on its own.

mm doctor (requiresAuth = false, requiresInit = false) is purpose-built for this: it returns authenticated + initialized booleans plus hints and 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 authenticated line: https://raw.githubusercontent.com/stripe/link-cli/refs/heads/main/skills/create-payment-credential/SKILL.md

MetaMask 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-cli v2.0.0):

  • Runtime guard throws CommandError("NOT_INITIALIZED", "Project not initialized.", "Run \mm init` to set up wallet and trading modes.")inruntime/Command.ts`.
  • "Initialized" is defined identically in the runtime guard and DoctorCommand.#isInitialized: a wallet mode must be set, and for server-wallet a trading mode too (byok needs only the wallet mode).
  • mm doctor has requiresAuth = false / requiresInit = false and returns authenticated + initialized booleans plus hints; the init hint is gated on authenticated && !initialized.
  • mm init show inherits requiresInit = true, so it throws NOT_INITIALIZED on an uninitialized project rather than reporting state.
  • mm auth status returns no initialization field.

Before/after validation (A/B test)

Ran two fresh agents against an identical CLI state — authenticated but not initialized (a real uat session with the wallet/trading mode cleared) — each told to follow a skill and accomplish "check the wallet balance". Only the skill differed.

Old skill (main) New skill (this PR)
Preflight mm --versionmm auth status mm --versionmm doctor
Detected the not-ready state? No — auth status reported authenticated: true, treated as "go" Yes — mm doctor reported initialized: false + hint
Ran mm wallet balance? Yes, prematurely No — refused per the gate
Outcome NOT_INITIALIZED runtime error Routed to mm init; no error
When the problem surfaced Reactively, mid-operation Proactively, at the gate

The 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 (--versiondoctorwallet 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

  • Logged-out session: mm doctor reports authenticated: false and the login hint only.
  • Logged-in, uninitialized session: mm doctor reports authenticated: true, initialized: false, and the "Authenticated but not initialized" hint.
  • After mm init: mm doctor reports initialized: true with no blocking hints.

cloudonshore and others added 4 commits June 21, 2026 19:33
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 chaitanyapotti merged commit 12cf8f4 into MetaMask:main Jun 22, 2026
11 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.

2 participants