Skip to content

Align OpenClaw integration with verified 2026.7.1 upstream behavior - #83

Merged
obaid merged 1 commit into
mainfrom
feature/openclaw-upstream-alignment
Aug 24, 2026
Merged

obaid merged 1 commit into
mainfrom
feature/openclaw-upstream-alignment

Conversation

@obaid

@obaid obaid commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the full recommendation set from the OpenClaw gap review. Every claim was verified against the shipped openclaw@2026.7.1 npm package (the online docs describe a newer release and disagree in several load-bearing places), then exercised end-to-end on a freshly provisioned DigitalOcean server: clean provision → agent install → key injection → live chat reply through the gateway RPC → skill deploy → fleet version reconciliation.

What changed

Auth — the 2026.7.x runtime reads credentials only from per-agent SQLite; auth-profiles.json is never read (and its presence corrupts auth heuristics). All writes replaced with openclaw models --agent X auth paste-api-key stdin injection; ChatGPT OAuth polling/disconnect moved to models auth list/logout --json (file-based detection was silently broken); subscription agents' provider slots are never overwritten.

Claude subscription (BYO) — new end-to-end flow: paste a claude setup-token, stored via paste-token, auth-order pinned, direct anthropic/ routing, heartbeats billed to the subscription, disconnect hooks on model change / pay-per-use switch. UI mirrors the ChatGPT flow with the upstream ToS caveats surfaced.

Routing — BYO Anthropic/OpenAI keys now route direct instead of dead-ending at OpenRouter with no credential; prompt-caching keys fixed for both route forms.

Config — agent add/update + Slack channel ops go through the gateway config RPC with baseHash optimistic locking (3 attempts, file-edit fallback for gateway-down); closes the three-writer clobber race and a Slack-token shell-injection hole. Removal reordered RPC-before-file-edit.

Fleet updates — new UpdateOpenClawVersionJob + hourly reconciliation via openclaw update --tag --yes; fixed version parsing that reinstalled OpenClaw on every agent update (live output is OpenClaw 2026.7.1 (hash); positional parses broke).

Retirements (verified) — OperatorPairingPatch (loopback CLI + gateway token bypasses pairing since upstream #95997; validated live: fresh server healthy with devices/paired.json absent), GatewayClient's OpenClaw arm, dead AgentBrowserProvider contract, _legacyUpdateAgent.

Browser — profiles switched to raw CDP attach-only (drops the npx chrome-devtools-mcp@latest runtime dependency of driver: existing-session; regains per-tab WS, element screenshots, downloads).

Provisioning — installer hardened (OPENCLAW_NO_PROMPT/NO_ONBOARD, loud failure); DO provisioning is retry-safe on volume-name collisions (found live during the Aug 24 DO API outage).

Verification

  • Full suite: 1140 passed (119 module-guard skips)
  • Adversarial code review (medium): 8 findings, all fixed or refuted-with-evidence
  • Live E2E on droplet provision-… (nyc1): all cloud-init steps, gateway healthy without pairing patch, SQLite auth store populated by injection, chat.send round-trip returned the expected reply, skill deploy with frontmatter normalization + snapshot bump, fleet job converged and recorded the version
  • Companion PRs: provision-skills feature/openclaw-upstream-alignment (skill deploy hardening), provision-openclaw-web feature/complete-channel-adapters (channel adapters)

Not included

  • composer.json/composer.lock local path-repo wiring for module-skills (dev-only, per deploy conventions)
  • The E2E droplet is left running for inspection — tear down when done

Every change here was verified against the shipped openclaw@2026.7.1 npm
package (not the online docs, which describe a newer release) and
exercised end-to-end on a freshly provisioned DigitalOcean server.

Auth (runtime reads SQLite only — auth-profiles.json is dead upstream):
- Replace every auth-profiles.json write with per-agent
  `openclaw models --agent X auth paste-api-key` injection (env job,
  install script, update script); the legacy files were never read on
  2026.7.x and corrupted auth-presence heuristics
- ChatGPT OAuth polling/disconnect moved from jq-on-file to
  `models auth list/logout --json` (pairing detection was broken)
- Subscription guards: never inject an api_key profile over a ChatGPT
  (openai) or Claude (anthropic) subscription agent's slot

Claude subscription (BYO) support:
- ClaudeAuthService (setup-token over piped stdin, order pinning,
  sanitized errors), controller + routes, migration, connect UI, tier
  wiring, disconnect hooks on model change / switch-to-pay-per-use

Model routing:
- BYO Anthropic/OpenAI keys now route direct (anthropic/, openai/)
  instead of dead-ending at OpenRouter without a credential; memoized
  per-team key lookups; prompt-caching keys fixed for both route forms

Config management:
- ConfigPatchService agent add/update + Slack ops now go through the
  gateway config RPC (config.get hash -> config.patch with baseHash,
  3 attempts, file-edit fallback) — closes the clobber race and a
  Slack-token shell-injection hole; removal reordered RPC-before-file

Fleet updates:
- UpdateOpenClawVersionJob + hourly reconciliation via
  `openclaw update --tag --yes` (no fleet mechanism existed); fixed
  version parses that reinstalled OpenClaw on every agent update
  (output is "OpenClaw 2026.7.1 (hash)" — positional parses broke)

Retirements (verified safe on 2026.7.1):
- OperatorPairingPatch: loopback CLI + gateway token bypasses device
  pairing entirely since #95997 — our only access path
- GatewayClient's OpenClaw arm (both call sites are Hermes-gated);
  dead AgentBrowserProvider contract; _legacyUpdateAgent

Browser:
- Profiles switched from driver=existing-session to raw CDP attach-only
  (no npx chrome-devtools-mcp subprocess; regains per-tab WS, element
  screenshots, downloads; attachOnly is honored on this path)

Provisioning hardening:
- Installer runs with OPENCLAW_NO_PROMPT/NO_ONBOARD and fails loudly
- ProvisionDigitalOceanServerJob is retry-safe (reuses a surviving
  volume by name instead of 409ing — found live during a DO outage)
@obaid
obaid merged commit 9a9e777 into main Aug 24, 2026
2 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.

1 participant