Skip to content

fix(onboarding): 3 fresh-install stalls — gateway.mode message, default agent, scope-rejection masking (draft)#74

Merged
LightDriverCS merged 4 commits into
mainfrom
aurelius/onboarding-hardening
Jun 23, 2026
Merged

fix(onboarding): 3 fresh-install stalls — gateway.mode message, default agent, scope-rejection masking (draft)#74
LightDriverCS merged 4 commits into
mainfrom
aurelius/onboarding-hardening

Conversation

@LightDriverCS

@LightDriverCS LightDriverCS commented Jun 17, 2026

Copy link
Copy Markdown

Scope

Three fresh-install onboarding stalls observed during a live local-model bring-up (customer Mac mini, openclaw 2026.6.2). Each is small and self-contained.

The three fixes

  1. gateway install message lied about its own behavior. Install already auto-sets gateway.mode=local when unset, then printed "No gateway.mode found. Set gateway.mode=local …" — an imperative that made operators redundantly run config set + restart. New message states what the code did and that no action is needed.
  2. openclaw agent errored with no target even when one agent exists. openclaw agent -m "…" (no --to/--agent/--session-*) threw "No target session selected" on a fresh box with exactly one agent (main). It now defaults to the sole configured agent (stderr hint), erroring only on 0/2+ (and listing the configured agents then).
  3. Scope rejection was masked by the embedded fallback. When the CLI device holds operator.read but a turn needs operator.write, the gateway closes with "pairing required: … more scopes". That transport-closed error was treated as embedded-fallback-worthy, so the CLI silently ran an embedded agent that picked a keyless openai/gpt-5.5 and died with a confusing auth error. Now a pairing/scope close throws a clear, actionable error pointing at openclaw devices approve --latest and does not fall back. Does not auto-grant scopes — authz stays operator-gated.

Touched surfaces

  • src/cli/daemon-cli/install.ts (+ test) — message
  • src/commands/agent-via-gateway.ts (+ test) — default-to-sole-agent; isGatewayPairingScopeError + intercept

User-visible behavior

Clearer install output; openclaw agent -m "…" works on a single-agent install; a scope-rejected turn tells you exactly how to fix it instead of failing on a phantom openai model. Multi-agent / explicit-target / normal-fallback behavior unchanged.

Firebase / deploy impact

None — CLI-only.

Local gates

  • vitest run affected suites — 78/78 (incl. 2 new regression tests: default-agent, scope-rejection-no-fallback)
  • tsc --noEmit — clean on touched files
  • oxlint — clean (incl. preserve-caught-error: thrown scope error carries { cause })

Known follow-up (NOT in this PR — genuine design decision, deferred)

  • Fresh agent defaulting to keyless openai/gpt-5.5 when only an Anthropic key is present. Auto-picking a per-provider default model non-interactively risks writing a wrong/deprecated model id — the provider plugin exposes a model list, not an authoritative single default (the wizard resolves this via an interactive picker). Correct fix = reuse the wizard's model selection at key-placement, or add an authoritative per-provider recommended-model source. With fix fix(memory-wiki): standardize page schema + repair pipeline #3 above, this now surfaces as a clear error rather than the old silent cascade.

🤖 Generated with Claude Code

Agent-Aurelius and others added 2 commits June 17, 2026 15:40
Two fresh-install onboarding stalls hit during a live local-model bring-up:

1. `gateway install` already auto-sets `gateway.mode=local` when it is unset
   (it writes the config), but then printed "No gateway.mode found. Set
   gateway.mode=local for managed gateway install." — an imperative that reads
   like the operator still has to act. Operators then redundantly ran
   `openclaw config set gateway.mode local` + restart. Message now states what
   the code actually did (defaulted to local) and that no action is needed.

2. `openclaw agent -m "…"` with no --to/--agent/--session-* errored "No target
   session selected" even on a fresh box where exactly one agent ("main")
   exists. It now defaults to the sole configured agent (emitting a stderr
   hint), and only errors when 0 or 2+ choices exist — where it now lists the
   configured agents instead of just pointing at `agents list`.

Tests: install.test.ts message assertion updated; new agent-via-gateway case
locks the default-to-sole-agent behavior. 77/77 in the two affected suites,
tsc --noEmit clean, oxlint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…e rejection

Third fresh-install onboarding stall from the same bring-up: when the CLI
device holds operator.read but a turn needs operator.write, the gateway closes
with "pairing required: device is asking for more scopes" — a transport-closed
error. The fallback path treated ALL transport errors as embedded-fallback
worthy, so it silently ran an embedded agent (which then picked a keyless
openai/gpt-5.5 and died with a confusing auth error), masking the real authz
problem.

Now a pairing/scope close is detected (isGatewayPairingScopeError) and the CLI
throws a clear, actionable error pointing at `openclaw devices approve --latest`
instead of falling back. Does NOT auto-grant scopes (authz stays operator-gated).

New regression test asserts the scope rejection throws the approve hint and does
NOT invoke the embedded agent. agent-via-gateway suite 57/57; install 20/20.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@LightDriverCS
LightDriverCS force-pushed the aurelius/onboarding-hardening branch from f351b28 to 41d2767 Compare June 17, 2026 22:01
@LightDriverCS LightDriverCS changed the title fix(onboarding): honest gateway.mode message + default to the sole agent (draft) fix(onboarding): 3 fresh-install stalls — gateway.mode message, default agent, scope-rejection masking (draft) Jun 17, 2026
@LightDriverCS
LightDriverCS marked this pull request as ready for review June 17, 2026 23:06

@Agent-Aurelius Agent-Aurelius left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anvil auto-approval — verdict READY, non-code-owned. Approved under the dedicated Anvil reviewer identity.

@github-actions

Copy link
Copy Markdown

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/acpx/npm-shrinkwrap.json

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions

Copy link
Copy Markdown

Dependency graph changes noted

This PR includes dependency graph changes. The dependency guard is informational because the PR author is a repository admin or a member of @openclaw/openclaw-secops.

  • Current SHA: b4c4147dfd2edf2db9fad22ba613016760709d5f
  • Trusted actor: @LightDriverCS
  • Trusted role: pull request author; repository admin

Security review is still recommended before merge when the dependency graph change is intentional.

@LightDriverCS
LightDriverCS merged commit faee1c4 into main Jun 23, 2026
153 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants