mirror of github.com/openclaw/openclaw https://openclaw.ai
Find a file
PollyBot13 b5b7ca44ac
fix(memory): read the searched workspace for explicit agents (#147072)
Closes #146939. Related: #140984.

## What Problem This Solves

Fixes `memory_get` returning a different file from `memory_search` when an explicitly owned multi-agent roster relies on inherited workspace paths.

## User Impact

Search results and subsequent reads agree on the agent's workspace without requiring a per-agent workspace pin. Explicit workspace overrides remain authoritative. No files move, no index reset or storage migration is required, and Markdown containment and read limits are unchanged.

For explicitly owned rosters, an unpinned first agent no longer implicitly reads the parent workspace merely because it appears first. A valid retained migration owner and sole-agent inheritance still follow canonical behavior. Raw reader inputs without explicit ownership keep their existing legacy behavior.

## Why This Change Was Made

The prior path repair in #140984 deliberately deferred workspace-ownership alignment. This PR proposes only that bounded alignment: core and explicitly owned memory-host reads share the compatibility-owner decision through a pure internal helper. The existing private path bridge avoids importing the full agent runtime. The original config object is preserved for retained migration-owner lookup; optional legacy reader IDs remain accepted.

### Maintainer choices — proposed, not previously approved

1. **Accept explicit-roster alignment (recommended and implemented).** Search's canonical workspace ownership is authoritative for reads too. Alternatively, retain the mismatch and require explicit workspace pins; this PR does not silently change search to match the old getter.
2. **Preserve legacy reader compatibility (implemented).** Inputs without `ownership: "explicit"` retain first-agent/default-marker inheritance. Broader normalization of those inputs is intentionally deferred, rather than changing the shipped reader contract in this fix.
3. **Keep adjacent policy out of scope (recommended).** No context-limit merging changes, shared-system-agent workspace redesign, public SDK entrypoint, or broader path allowlist. Those require separate decisions.

ClawSweeper's source review supports this direction but requests a compatibility decision; it is not maintainer approval. Please review the ownership choice before merge. Rollback is reverting this change; the issue's explicit-workspace-pin mitigation remains available.

## Evidence

### After-fix real Gateway proof — September 13, 2026

Built candidate `be5a589a0ee148b54c51f6876ef5281ee9b29cb5`, Node 26.8.1/macOS. Used a loopback-only Gateway, registered Memory Core tools through HTTP `POST /tools/invoke`, synthetic files and real on-disk SQLite state, `provider: none`, and vectors disabled. No test-helper imports, provider calls, or production configuration/state changes.

| Setup | Actual search → get result |
| --- | --- |
| Fresh explicit two-agent roster, neither agent pinned; parent contains a decoy | main: `USER.md`, `status=ok`, `Orchid proof main`; other: `USER.md`, `status=ok`, `Orchid proof other` |
| Fresh setup, parent traversal for each agent | `MEMORY_PATH_NOT_ALLOWED` |
| Installed 2026.9.3, existing explicit workspace pins | main/other: `USER.md`, `status=ok`, matching `Orchid upgrade main` / `Orchid upgrade other` |
| Same shipped-created state after candidate Doctor migration and candidate Gateway startup | Both agents return those same markers with `status=ok` |

For each agent, passed the search result's path/start line/inclusive line count into `memory_get`. Stopped the shipped Gateway before switching binaries. Candidate initially refused the older session-identity database; followed its supported `doctor --fix --non-interactive` instruction (exit 0, both agent databases v19→v20), then repeated the actual HTTP flow. Both existing workspace pins were preserved exactly, and SHA-256 checks showed all three synthetic `USER.md` files unchanged. Doctor did change normal config metadata/defaults; the whole config was **not** unchanged. All proof Gateways were stopped.

This is fresh-runtime and shipped-created-state/Doctor migration proof, **not** an installer, `openclaw update` driver, or live-user upgrade test. Retained legacy-owner shapes beyond these fixtures remain covered by focused tests, not claimed as live proof. The schema migration belongs to the candidate's existing upgrade path; this six-file patch introduces no schema or embedding-metadata changes. Maintainer acceptance of explicit-roster read-root alignment remains required.

CI at this evidence update: the model-login catalog timing case in [large-26](https://github.com/openclaw/openclaw/actions/runs/34761804381/job/103735936253) failed, making the aggregate gate red. Its fixture disables memory and uses one pinned agent without explicit ownership; likely unrelated, but no matching base failure was verified. No CI pass is claimed.

- Focused validation: 162 tests passed across six files (one existing skipped test), including the real-manager tool regression and package-boundary contracts.
- Final-head `node scripts/check-changed.mjs` passed: core and test types, core/extension lint, formatting, dead-export scans, package/SDK boundaries, and runtime import-cycle checks. `git diff --check` passed.
- Full `pnpm build` passed in 3m26s, including plugin SDK exports, CLI bootstrap imports, built plugin-loading checks, and Control UI build. After that build, the only patch change moved an unchanged re-export below imports for lint; the rebase added only unrelated ACP tests. The repository-wide test suite was not run.
- Tests-first reproduction on upstream main: both roster orders returned the parent decoy through `memory_get` after real SQLite-backed `memory_search` found the agent marker.
- The regression exercises both agents, both roster orders, returned path/line readback, and rejection of parent traversal. It uses temporary files and databases with embeddings disabled; no provider request or private installation data.
- Compatibility coverage includes explicit workspace overrides, retained/removed migration owners, ignored legacy markers under explicit ownership, optional legacy IDs, sole/duplicate agents, and absent/empty rosters. Existing legacy path, file-reader, core ownership, and package-boundary coverage is retained.
- Independent clean-context P0–P3 source review found no actionable findings. The repository Auto Review CLI was also attempted but could not authenticate; no successful CLI review is claimed.

AI-assisted implementation and review. Maintainer approval remains required; no merge or automatic repair authority is inferred from the issue labels.


---

## Maintainer addendum — September 14, 2026

The ownership choices proposed above are accepted. This addendum records the final shared legacy-data owner, the preserved durable runtime default, and the refreshed proof. Earlier evidence remains tied to its stated revision.

### Problem

Memory search finds an agent's file, but `memory_get` returns the parent's different file as success.

### Fix and impact

Search and explicit memory reads now share one lightweight legacy-data owner. The two existing cached facts stay with the agent owner. Raw reader behavior, optional IDs, workspace pins, home/profile handling, and extra paths remain supported. No schema, migration, config key, protocol, or dependency changes.

Owner decision: explicit-roster reads must return the searched workspace's file, never a different parent file. This ends the explicit-roster exception retained in #140984. To retain the parent as an agent's workspace, configure that workspace explicitly. Legacy data ownership remains separate from the durable runtime default, preserving #146246.

Production growth is reduced from 46 to 38 net lines:

- `agent-roster.ts` moves existing roster readers into a lightweight module and owns the shared data decision.
- `agent-scope-config.ts` shrinks by 96 lines while preserving public exports and both cache lifetimes.
- Memory-host `config-utils.ts` adds eight net lines to preserve raw-reader compatibility and use the shared owner for explicit inputs.
- `openclaw-runtime-paths.ts` adds the one export needed by that call.

### Evidence

- Main `5576f256da`: the three unpinned regression rows fail with `status: ok` and `text: Parent decoy`; the pinned control passes. Command: `node scripts/run-vitest.mjs extensions/memory-core/src/tools.real-manager.test.ts -t 'reads the indexed agent file with explicit ownership'`.
- Retained HTTP proof at accepted `a016f35b265a96d4cdfd5d43dbf12d461ae417d2` (the rebuilt branch has identical owner files): real Gateway `POST /tools/invoke`, search then get, covers both roster orders, a non-first system agent, explicit pins, and parent traversal. Eight reads return the known agent file bytes; eight traversals are rejected.
- Fresh merge `f48cf5fc4eb0e717f252fefde7929632f24d494a`, parents candidate above and main `f6d984fcbe`: 297 tests pass, one existing skip, across the owner, memory, session/auth, and Doctor suites below.
- Local production/test type checks, changed-file type-aware lint, formatting, architecture, unused-export, line-count, and assertion checks pass. The assertion allowance only shrinks.
- Retained 2026.9.3-created state proof preserves pins, file hashes, and runtime default through Doctor/restart. This proves state compatibility, not the installed update driver.
- Earlier local matrix replay was stopped; its historical failures remain recorded. Current exact-head CI run [34806299349](https://github.com/openclaw/openclaw/actions/runs/34806299349) completed successfully at `1c3602c201d65ed43e45c4c1c856fe4fcc696dc8`, with every executed job passing.

<details>
<summary>HTTP requests and fresh-merge test command</summary>

The isolated Gateway runs through `pnpm openclaw gateway run --port <isolated-port> --bind loopback`.

```json
{"agentId":"main","tool":"memory_search","args":{"query":"AGENT_MAIN_ORCHID","corpus":"memory"}}
{"agentId":"main","tool":"memory_get","args":{"path":"USER.md","from":1,"lines":3}}
{"agentId":"main","tool":"memory_get","args":{"path":"../USER.md","from":1,"lines":2}}
```

The search-returned path and line range drive the read. The read returns two lines: `# main`, followed by `AGENT_MAIN_ORCHID searched source`. Traversal returns `MEMORY_PATH_NOT_ALLOWED`.

```sh
node scripts/run-vitest.mjs \
  packages/memory-host-sdk/src/host/config-utils.test.ts \
  packages/memory-host-sdk/src/host/read-file.test.ts \
  packages/memory-host-sdk/src/host/read-file-manager-compat.test.ts \
  extensions/memory-core/src/tools.real-manager.test.ts \
  src/agents/agent-scope-config.test.ts \
  src/agents/legacy-inherited-auth-dir.test.ts \
  src/plugins/contracts/extension-package-project-boundaries.test.ts \
  src/config/legacy.roster.test.ts \
  src/commands/sessions.default-agent-store.test.ts \
  src/commands/doctor/shared/legacy-config-migrations.agent-rosters.test.ts \
  src/commands/doctor/shared/legacy-config-migrations.runtime.system-agent.test.ts \
  src/commands/doctor/shared/default-agent-role-materialization.test.ts \
  src/commands/doctor/shared/default-agent-role-materialization.write.test.ts \
  src/commands/doctor-config-flow.workspace-persistence.test.ts \
  src/agents/agent-scope.test.ts \
  src/agents/agent-scope.workspace-inference.test.ts
```

</details>

## Consumers

The moved roster types retain their `index`, `key`, and `kind` fields. The following typed read sites preserve their source-location contracts; generic word matches elsewhere are not consumers of these fields.

<details>
<summary>Preserved roster-field callers</summary>

census: generic index reviewed — 19 callers listed

- `src/agents/sandbox/secret-owner.ts:53:42` — Report unresolved SSH secret references at the selected agent source path.
- `src/cli/config-model-validation.ts:117:90`, `src/cli/config-model-validation.ts:221:62` — Locate model validation issues and test whether edited paths change model ownership at the correct keyed entry or list index.
- `src/commands/doctor/shared/context-engine-host-compat.ts:113:90`, `src/commands/doctor/shared/context-engine-host-compat.ts:153:90` — Locate context-engine host compatibility warnings and repairs at the source agent path.
- `src/commands/doctor/shared/exec-safe-bins.ts:85:35` — Locate executable allowlist warnings at the source agent tools.exec path.
- `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:91:90`, `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:293:90` — Locate plugin tool allowlist warnings at the source agent path.
- `src/config/io.write-prepare.ts:993:71`, `src/config/io.write-prepare.ts:1000:41` — Preserve original roster representation, legacy occurrence identity, explicit writes/deletions, authored reference restoration, and source paths across config writes.
- `src/config/validation-core.ts:159:36`, `src/config/validation-core.ts:281:90`, `src/config/validation-core.ts:335:55` — Locate avatar, model-policy, and sandbox environment errors at the authored keyed entry or original list index.
- `src/config/validation.ts:715:90` — Attach heartbeat target validation issues to the correct authored agent path.
- `src/secrets/runtime-config-collectors-core.ts:536:35` — Locate agent text-to-speech secret assignments at the source agent path.
- `src/secrets/runtime-config-collectors-memory.ts:125:90` — Locate memory secret assignments at the source agent path; the separate unchanged implicit-agent producer supplies the legacy key when no roster exists.
- `src/secrets/runtime-config-collectors-sandbox.ts:75:90` — Carry the source agent path into sandbox secret collection candidates.
- `src/security/dangerous-config-flags-core.ts:50:36` — Report dangerous flags at canonical keyed paths when an ID exists; retain original list index for an ID-less legacy row.
- `src/skills/workshop/tool-policy-diagnostic.ts:49:40` — Report canonical keyed tool-policy paths when an ID exists; retain original list index for an ID-less legacy row.

census: generic key reviewed — 18 callers listed

- `src/agents/sandbox/secret-owner.ts:52:45` — Report unresolved SSH secret references at the selected agent source path.
- `src/cli/config-model-validation.ts:117:60`, `src/cli/config-model-validation.ts:221:42` — Locate model validation issues and test whether edited paths change model ownership at the correct keyed entry or list index.
- `src/commands/doctor/shared/context-engine-host-compat.ts:113:60`, `src/commands/doctor/shared/context-engine-host-compat.ts:153:60` — Locate context-engine host compatibility warnings and repairs at the source agent path.
- `src/commands/doctor/shared/exec-safe-bins.ts:84:38` — Locate executable allowlist warnings at the source agent tools.exec path.
- `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:91:60`, `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:293:60` — Locate plugin tool allowlist warnings at the source agent path.
- `src/config/io.write-prepare.ts:1001:44` — Preserve original roster representation, legacy occurrence identity, explicit writes/deletions, authored reference restoration, and source paths across config writes.
- `src/config/validation-core.ts:158:39`, `src/config/validation-core.ts:281:60`, `src/config/validation-core.ts:334:58` — Locate avatar, model-policy, and sandbox environment errors at the authored keyed entry or original list index.
- `src/config/validation.ts:715:60` — Attach heartbeat target validation issues to the correct authored agent path.
- `src/secrets/runtime-config-collectors-core.ts:535:38` — Locate agent text-to-speech secret assignments at the source agent path.
- `src/secrets/runtime-config-collectors-memory.ts:125:60` — Locate memory secret assignments at the source agent path; the separate unchanged implicit-agent producer supplies the legacy key when no roster exists.
- `src/secrets/runtime-config-collectors-sandbox.ts:75:60` — Carry the source agent path into sandbox secret collection candidates.
- `src/security/dangerous-config-flags-core.ts:46:44` — Report dangerous flags at canonical keyed paths when an ID exists; retain original list index for an ID-less legacy row.
- `src/skills/workshop/tool-policy-diagnostic.ts:46:41` — Report canonical keyed tool-policy paths when an ID exists; retain original list index for an ID-less legacy row.

census: generic kind reviewed — 64 callers listed

- `src/agents/agent-roster.ts:23:15`, `src/agents/agent-roster.ts:35:15` — Select the raw representation before projecting entries; preserve entries precedence and reject invalid representation values.
- `src/agents/agent-scope-config.ts:281:15`, `src/agents/agent-scope-config.ts:294:15`, `src/agents/agent-scope-config.ts:329:15`, `src/agents/agent-scope-config.ts:334:15`, `src/agents/agent-scope-config.ts:316:47` — Preserve direct and mutable roster lookup branches; source.kind in the batch index preserves keyed clone-on-read and legacy list identity.
- `src/agents/sandbox/secret-owner.ts:51:25` — Report unresolved SSH secret references at the selected agent source path.
- `src/cli/config-cli-roster.ts:17:21`, `src/cli/config-cli-roster.ts:35:55`, `src/cli/config-cli-roster.ts:53:19`, `src/cli/config-cli-roster.ts:58:17`, `src/cli/config-cli-roster.ts:90:22`, `src/cli/config-cli-roster.ts:107:38` — Preserve list order and keyed/list path translation across CLI mutations and canonicalization.
- `src/cli/config-model-validation.ts:117:14`, `src/cli/config-model-validation.ts:220:14`, `src/cli/config-model-validation.ts:221:14` — Locate model validation issues and test whether edited paths change model ownership at the correct keyed entry or list index.
- `src/commands/doctor-config-flow.ts:255:45` — Read migrated keyed entries to persist the legacy workspace and stamp explicit ownership for multiple agents.
- `src/commands/doctor/shared/context-engine-host-compat.ts:113:14`, `src/commands/doctor/shared/context-engine-host-compat.ts:153:14` — Locate context-engine host compatibility warnings and repairs at the source agent path.
- `src/commands/doctor/shared/exec-safe-bins.ts:83:16` — Locate executable allowlist warnings at the source agent tools.exec path.
- `src/commands/doctor/shared/legacy-config-core-migrate.ts:30:41`, `src/commands/doctor/shared/legacy-config-core-migrate.ts:35:25`, `src/commands/doctor/shared/legacy-config-core-migrate.ts:45:19`, `src/commands/doctor/shared/legacy-config-core-migrate.ts:46:20`, `src/commands/doctor/shared/legacy-config-core-migrate.ts:108:107` — Validate representation/value agreement, repair the selected roster in its existing shape, and name that shape in repair messages.
- `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:91:14`, `src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts:293:14` — Locate plugin tool allowlist warnings at the source agent path.
- `src/config/io.write-prepare.ts:892:14`, `src/config/io.write-prepare.ts:951:20`, `src/config/io.write-prepare.ts:1146:15`, `src/config/io.write-prepare.ts:1177:25`, `src/config/io.write-prepare.ts:1185:26`, `src/config/io.write-prepare.ts:1218:23`, `src/config/io.write-prepare.ts:1233:23`, `src/config/io.write-prepare.ts:1255:25`, `src/config/io.write-prepare.ts:1269:23`, `src/config/io.write-prepare.ts:1287:21`, `src/config/io.write-prepare.ts:1330:23`, `src/config/io.write-prepare.ts:1352:21`, `src/config/io.write-prepare.ts:1354:21`, `src/config/io.write-prepare.ts:1450:23`, `src/config/io.write-prepare.ts:1455:27`, `src/config/io.write-prepare.ts:1467:42`, `src/config/io.write-prepare.ts:1532:72`, `src/config/io.write-prepare.ts:1546:23`, `src/config/io.write-prepare.ts:1551:25`, `src/config/io.write-prepare.ts:993:25`, `src/config/io.write-prepare.ts:999:22` — Preserve original roster representation, legacy occurrence identity, explicit writes/deletions, authored reference restoration, and source paths across config writes.
- `src/config/legacy.roster.ts:106:23`, `src/config/legacy.roster.ts:117:35` — Select legacy list conversion, then consume the keyed roster after migration.
- `src/config/validation-core.ts:157:12`, `src/config/validation-core.ts:281:14`, `src/config/validation-core.ts:333:34` — Locate avatar, model-policy, and sandbox environment errors at the authored keyed entry or original list index.
- `src/config/validation.ts:715:14` — Attach heartbeat target validation issues to the correct authored agent path.
- `src/gateway/server-methods/config.ts:528:15`, `src/gateway/server-methods/config.ts:531:15` — Enumerate explicitly authored agent IDs in either representation before rejecting unapproved removals.
- `src/plugins/provider-auth-choice-helpers.ts:304:52`, `src/plugins/provider-auth-choice-helpers.ts:306:52` — Write normalized agent model references back using the original keyed or list representation.
- `src/secrets/runtime-config-collectors-core.ts:534:16` — Locate agent text-to-speech secret assignments at the source agent path.
- `src/secrets/runtime-config-collectors-memory.ts:125:14` — Locate memory secret assignments at the source agent path; the separate unchanged implicit-agent producer supplies the legacy key when no roster exists.
- `src/secrets/runtime-config-collectors-sandbox.ts:75:14` — Carry the source agent path into sandbox secret collection candidates.
- `src/security/dangerous-config-flags-core.ts:45:21` — Report dangerous flags at canonical keyed paths when an ID exists; retain original list index for an ID-less legacy row.
- `src/skills/workshop/tool-policy-diagnostic.ts:45:19` — Report canonical keyed tool-policy paths when an ID exists; retain original list index for an ID-less legacy row.

</details>

Registered memory tools use the shared data owner for explicit workspace reads. Search manager lookup, forget/reset/backfill, session/auth data locations, and Doctor materialization retain their existing owner contracts. There is no new state writer; config-identity provenance and the separate data/runtime batch facts keep their existing lifetimes.

### Contributor-branch refresh

The accepted content is rebuilt on the original contributor head `be5a589a0ee148b54c51f6876ef5281ee9b29cb5`, followed by a plain merge of main `ae5a4b4a55` and the five maintainer commits in order. There were no conflicts or manual resolutions, and all five messages are unchanged.

The resulting head `1c3602c201d65ed43e45c4c1c856fe4fcc696dc8` has the same complete tree as the accepted revision merged with that main. The 16-file command above passed again on this head: 297 tests, one existing skip, exit 0.


The unchanged local preflight passed on this same head in a physical checkout with its own dependencies. It covered type-aware lint, production types, core/extension/script/root-test types, and protocol checks. The initial nested-checkout attempt failed only the declaration-input isolation guard; physical isolation resolved it without disabling any check.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-14 10:47:19 +05:30
.agents
.claude
.github
.vscode
apps chore(i18n): refresh native locales (#147899) 2026-09-14 05:07:29 +00:00
CHANGELOG
config fix(memory): read the searched workspace for explicit agents (#147072) 2026-09-14 10:47:19 +05:30
custodian-skills
deploy
docs fix(update): explain invalid config during database preflight (#147771) 2026-09-13 22:16:54 -07:00
examples/ai-chat
extensions fix(memory): read the searched workspace for explicit agents (#147072) 2026-09-14 10:47:19 +05:30
git-hooks
packages fix(memory): read the searched workspace for explicit agents (#147072) 2026-09-14 10:47:19 +05:30
patches
qa
scripts fix(update): explain invalid config during database preflight (#147771) 2026-09-13 22:16:54 -07:00
security
skills fix(skills): keep sag available with alternate credentials (#147685) 2026-09-14 08:26:59 +05:30
src fix(memory): read the searched workspace for explicit agents (#147072) 2026-09-14 10:47:19 +05:30
test fix(ci): skip SDK rendering for identical revisions (#147572) 2026-09-14 12:54:46 +08:00
ui fix: background requests delay opening chats (#147845) 2026-09-13 22:07:33 -07:00
.crabbox.yaml
.dockerignore
.env.example
.gitattributes
.gitignore
.npmrc
.oxfmtrc.jsonc
.oxlintrc.json
.pre-commit-config.yaml
.semgrepignore
AGENTS.md
appcast.xml
CHANGELOG.md
CLAUDE.md
CONTRIBUTING.md
docker-compose.yml
Dockerfile
fly.toml
LICENSE
node-runtime-recovery.d.mts
node-runtime-recovery.mjs
node-runtime-update.d.mts
node-runtime-update.mjs
node-sqlite.d.mts
node-sqlite.mjs
node-version.d.mts
node-version.mjs
openclaw.mjs
package.json test(e2e): retire obsolete plugin staging smoke (#147555) 2026-09-14 12:30:54 +08:00
pnpm-lock.yaml fix: restore plugin networking under Bun (#147421) 2026-09-13 19:25:19 -07:00
pnpm-workspace.yaml fix(codex): isolate hook imports and cancel disconnected waits (#147444) 2026-09-14 07:14:04 +08:00
README.md
render.yaml
SECURITY.md
taxonomy.yaml
THIRD_PARTY_NOTICES.md
tsconfig.core.json
tsconfig.extensions.json
tsconfig.extensions.projects.json
tsconfig.json refactor(paths): centralize home directory resolution (#145866) 2026-09-13 18:58:17 -07:00
tsconfig.scripts.json
tsconfig.ui.json
tsdown.ai.config.ts
tsdown.config.ts fix(setup): resume interrupted setup in the approved workspace (#147705) 2026-09-14 10:43:12 +08:00
VISION.md
vitest.config.ts

OpenClaw 🦞 — Your assistant, on your devices, in your chats

OpenClaw — EXFOLIATE! EXFOLIATE! Your AI assistant, running on your own devices.

CI status npm version Node.js version License: MIT Discord

OpenClaw is an open-source AI assistant that runs on your own computer and meets you in the channels you already use: Discord, iMessage, Slack, Teams, Telegram, WhatsApp, and 20+ more, plus native apps for macOS, iOS, Android, Windows, and Linux. One Gateway runs it as a personal assistant on a laptop or as a shared team deployment; configuration is the only difference.

Yours, with no catch. State, memory, and credentials live on your hardware. Models and agent harnesses (Claude, Codex, local models) are plugins you can swap without changing anything else. Your prompts go to the model provider and chat platforms you configure, plus any diagnostics export you enable yourself; by default OpenClaw itself phones home for nothing but a daily version check, anonymous feature statistics are opt-in, and update.checkOnStart: false disables both (what OpenClaw sends). OpenClaw is stewarded by the OpenClaw Foundation, an independent 501(c)(3), and has no paid tier, hosted service, or token. The architecture case — trusted gateway, untrusted execution, deterministic policy — is in Why OpenClaw.

Website · Docs · Getting started · Why OpenClaw · Showcase · FAQ · Vision · DeepWiki

Install

The installer supports macOS, Linux, and Windows. It provisions a supported Node.js runtime when needed.

# macOS / Linux / WSL2
curl -fsSL https://openclaw.ai/install.sh | bash
# Windows PowerShell
iwr -useb https://openclaw.ai/install.ps1 | iex

Already manage Node.js? Install the published package instead (Node 24.16+ or 26.1+; Node 26 recommended):

npm install -g openclaw@latest --allow-scripts=openclaw

That command is for npm 12 or npm 11.16+. On npm 11.15 and earlier, omit --allow-scripts=openclaw. See the installation guide for the lifecycle script contract, Docker, Nix, and other deployment paths.

Quick start

On a fresh install, the installer scripts start onboarding automatically. Complete the wizard they open. If you installed the package directly with npm, pnpm, or Bun, run:

openclaw onboard --install-daemon

After onboarding:

openclaw gateway status
openclaw dashboard

Onboarding verifies model access, creates the workspace, and configures the Gateway. The last command opens the Control UI; send a message there to confirm the assistant is working. See the getting started guide for channel setup and troubleshooting.

How it fits together

  • The Gateway is the local control plane for sessions, tools, events, and channel connections.
  • The Control UI, CLI, and TUI connect to the Gateway.
  • Channels bring the assistant to WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, and other messaging services.
  • Companion apps and nodes add voice, Canvas, camera, screen, and device-local actions on supported platforms.

OpenClaw works with hosted and local model providers. Its tools, skills, and plugins extend what an assistant can do.

Security

Treat inbound messages as untrusted input. DM-capable channels pair unknown senders by default; approve a pairing request with openclaw pairing approve <channel> <code>.

Tools run on the host for the main session unless you configure sandboxing. Read the security guide, exposure runbook, and sandboxing guide before connecting other users or exposing the Gateway remotely.

Documentation

Goal Start here
Configure models and auth Models · Model providers
Connect a messaging service Channels
Add tools, skills, and plugins Tools · Skills · Plugins · ClawHub
Run apps and device nodes Platforms · Nodes
Use the CLI and chat commands CLI reference · Slash commands
Configure or operate the Gateway Configuration · Architecture · Updating · Release channels

Development

The repository is a pnpm workspace. Plain npm install at the repository root is not supported.

git clone https://github.com/openclaw/openclaw.git
cd openclaw
pnpm install
pnpm build
pnpm ui:build

See CONTRIBUTING.md for the contribution workflow and the source setup guide for the development loop.

Governance

OpenClaw is developed in the open by the OpenClaw Foundation, an independent 501(c)(3). The Foundation employs the core team and signs releases. Donors and infrastructure sponsors support the Foundation; none of them own or direct the project. OpenAI is a donor, not an owner.

Community

See CONTRIBUTING.md for maintainers and contribution guidelines; AI-assisted PRs are welcome.

Use the issue chooser for bugs and feature requests, ask setup questions in Discord, and report vulnerabilities through SECURITY.md. New capabilities usually belong in plugins built on the plugin SDK and shared through ClawHub.

OpenClaw was built for Molty, a space lobster AI assistant, by Peter Steinberger and the community. Explore the project lore, soul.md, Peter's site, Star History, and @openclaw.

Special thanks to Mario Zechner for his support and for pi, and to Adam Doppelt for the lobster.bot domain.

Donors and sponsors

The Foundation is funded by donors including Amazon, Lobster Computer Company, Offline Holdings, OpenAI, Red Hat, and the University of Michigan, with infrastructure support from Blacksmith, Convex, GitHub, NVIDIA, and Vercel.

Blacksmith Convex GitHub NVIDIA OpenAI Red Hat Vercel

Contributors

Thanks to all clawtributors:

steipete vincentkoc Takhoffman obviyus gumadeiras Mariano Belinky vignesh07 joshavant scoootscooob jacobtomlinson shakkernerd sebslight tyler6204 ngutman thewilloftheshadow Sid-Qin mcaxtr eleqtrizit BunsDev cpojer Glucksberg osolmaz bmendonca3 jalehman huntharo neeravmakwana openperf joshp123 pgondhi987 altaywtf quotentiroler liuxiaopai-ai rodrigouroz frankekn drobison00 zerone0x onutc ademczuk ImLukeF hydro13 hxy91819 coygeek dutifulbob sliverp Elonito robbyczgw-cla joelnishanth echoVic sallyom yinghaosang BradGroux christianklotz odysseus0 hclsys byungsker pashpashpash stakeswky github-actions[bot] xinhuagu MonkeyLeeT 100yenadmin mcinteerj samzong chilu18 darkamenosa widingmarcus-cyber cgdusek Lukavyi davidrudduck VACInc MoerAI velvet-shark HenryLoenwind omarshahine bohdanpodvirnyi Verite Igiraneza akramcodez Kaneki-x aether-ai-agent joaohlisboa MaudeBot davidguttman justinhuangcode lml2468 wirjo iHildy mudrii advaitpaliwal czekaj dlauer Solvely-Colin feiskyer brandonwise conroywhitney mneves75 jaydenfyi davemorin joeykrug kevinWangSheng pejmanjohn Lanfei liuy lc0rp teconomix omair445 dorukardahan mmaps Tobias Bischoff adhitShet pandego bradleypriest bjesuiter grp06 shadril238 kesku YuriNachos vrknetha smartprogrammer93 nachx639 jnMetaCode Phineas1500 dingn42 geekhuashan Nanako0129 AytuncYildizli BruceMacD jjjojoj mvanhorn bugkill3r rahthakor GodsBoy SARAMALI15792 Radek Paclt Elarwei001 ingyukoh SnowSky1 lewiswigmore Hiroshi Tanaka aldoeliacim Jakub Rusz Tony Dehnke roshanasingh4 zssggle-rgb adam91holt graysurf xadenryan sfo2001 Jamieson O'Reilly hsrvc tomsun28 BillChirico carrotRakko ranausmanai arkyu2077 hoyyeva luoyanglang sibbl gregmousseau sahilsatralkar akoscz rrenamed YuzuruS Hongwei Ma mitchmcalister juanpablodlc shtse8 thebenignhacker nimbleenigma Linux2010 shichangs efe-arv Hsiao A nabbilkhan ayanesakura lupuletic polooooo xaeon2026 shrey150 taw0002 dinakars777 giulio-leone nyanjou meaningfool kunalk16 ide-rea Jonathan Jing yelog markmusson kiranvk-2011 Sathvik Veerapaneni rogerdigital artwalker azade-c chinar-amrutkar maxsumrall Minidoracat unisone ly85206559 Sam Padilla AnonO6 afurm 황재원 Leszek Szpunar Mrseenz Yida-Dev kesor mazhe-nerd Harald Buerbaumer magimetal Hiren Patel BinHPdev RyanLee-Dev cathrynlavery al3mart JustYannicc abhisekbasu1 dbhurley Kris Wu tmimmanuel JustasM Simantak Dabhade NicholasSpisak natefikru dunamismax Simone Macario ENCHIGO xingsy97 emonty jadilson12 Yi-Cheng Wang Mathias Nagler Sean McLellan gumclaw RichardCao MKV21 petter-b CodeForgeNet Johnson Shi durenzidu dougvk Whoaa512 zimeg Tseka Luk Ryan Haines ufhy Daan van der Plas bittoby XuHao Lucenx9 HeMuling AaronLuo00 YUJIE2002 DhruvBhatia0 Divanoli Mydeen Pitchai Bronko rubyrunsstuff rabsef-bicrym IVY-AI-gif pvtclawn stephenschoettler Dale Babiy LeftX David Gelberg Engr. Arif Ahmed Joy Masataka Shinohara 2233admin ameno- battman21 bcherny bobashopcashier dguido druide67 guirguispierre jzakirov loganprit martinfrancois neo1027144-creator RealKai42 schumilin shuofengzhang solstead hengm3467 chziyue James L. Cowan Jr. scifantastic ryan-crabbe alexfilatov Luckymingxuan HollyChou badlogic Daniel Hnyk dan bachelder heavenlost shad0wca7 Jared kiranjd Mars Kim seheepeak tsavo McRolly NWANGWU dashed Shuai-DaiDai Subash Natarajan emanuelst magendary LI SHANXIN j2h4u bsormagec mjamiv Lalit Singh Jessy LANGE buddyh Aaron Zhu F_ool Ben Stein Lyle Ping popomore Dithilli fal3 mkbehr mteam88 gupsammy Shailesh Garnet Liu Thorfinn Protocol-zero-0 Paul van Oorschot Patrick Yingxi Pan Ptah.ai 정우용 artuskg Anandesh-Sharma zidongdesign innocent-children El-Fitz arthurbr11 jackheuberger Sergiusz Xu Gu hyojin jeann2013 jogelin rmorse scz2011 Andyliu benithors xiwuqi Alvin AARON AGENT Derek YU Marvin Andrew Jeon stain lu OpenCils Stefan Galescu SP Michael Flanagan Gracie Gould cash-echo-bot visionik WalterSumbon huangcj krizpoon rodbland2021 Thomas M sar618 fagemx daymade Tyson Cung Igor Markelov Eng. Juan Combetto connorshea bonald Keenan nachoiacovino zhumengzhu Amine Harch el korane zhoulc777 Alex Navarro Tanwa Arpornthip TIHU Aftabbs Alex-Alaniz jarvis-medmatic Tom Ron day253 Jaaneek Justin Song ziomancer shayan919293 Edward Roger Chien Michael Lee Tomáš Dinh Ian Derrington Lucky peschee Harry Cui Kepler julianengel markfietje Dakshay Mehta TheRipper Dominic danielwanwx Seungwoo hong Youyou972 boris721 damoahdominic dan-dr doodlewind kkarimi brokemac79 ozbillwang Ravish Gupta Jason Hargrove BrianWang1990 Joshua McKiddy Fologan Anonymous Amit v1p0r Ajay Elika Iranb Yonatan codexGW Shaun Tsai TideFinder Chase Dorsey tda 0xJonHoldsCrypto akyourowngames clawdinator[bot] koala73 sircrumpet thesomewhatyou zats Accunza Joly0 Hanna Jeremiah Lowin peetzweg/ Skyler Miao tumf Hiago Silva Nate lidamao633 Cklee CornBrother0x DukeDeSouth Sahan CashWilliams Felix Lu AdeboyeDN Rohan Santhosh Kumar Srinivas Pavan h0tp Neo Tianworld neverland asklee-klawd Yuting Lin constansino ghsmc ibrahimq21 irtiq7 kelvinCB mitsuhiko nohat santiagomed suminhthanh svkozak 张哲芳 Ho Lim Toven R. Desmond 游乐场 Reed Aditya Chaudhary Sam Andy Rajat Joshi cyb1278588254 Zoher Ghadyali Manik Vahsith tarouca MrBrain Daniel Zou Lilo Jason SUMUKH Bakhtier Sizhaev Ganghyun Kim AkashKobal Brian wu-tian807 Vasanth Rao Naik Sabavat Kinfey Artemii VibhorGautam John Rood velamints2 Benji Peng JINNYEONG KIM Rahul kumar Pal Rockcent Limitless 24601 awkoy dawondyifraw google-labs-jules[bot] henrino3 Kansodata kaonash p6l-richard pi0 skainguyen1412 Starhappysh xdanger Penchan scald Serhii a Doğu Abaris ysqander andranik-sahakyan Wangnov Austin lisitan Rishi Vhavle Frank Harris Kenny Lee Alice Losasso edincampara Felix Hellström Varun Chopra wangai-studio sleontenko Yassine Amjad Anton Eicher Drake Thomsen Hinata Kaga (samon) andreabadesso chenxin-yan cordx56 dvrshil MarvinCui Yeom-JinHo Jeremy Mumford Charlie Niño Sharoon Sharif Oren MattQ Parker Todd Brooks Yufeng He Milofax Steve (OpenClaw) zhoulf1006 Jonatan Sebastian B Otaegui Matthew ABFS Tech alexstyl Ethan Palm Qkal cygaar Umut CAN Jakob antons austinm911 mahmoudashraf93 philipp-spiess pkrmf joshrad-dev factnest365-ops yingchunbai AJ (@techfren) Marchel Fahrezi futhgar Zhang Rémi Dan Ballance Eric Su Kimitaka Watanabe Justin Ling Raymond Berger lutr0 claude AngryBird Fabian Williams 0x4C33 8BlT atalovesyou erikpr1994 jonasjancarik longmaba mitschabaude-bot thesash Max easternbloc chrisrodz gabriel-trigo manmal neist wes-davis manuelhettich sktbrd larlyssa pcty-nextgen-service-account Syhids tmchow Marc Gratch xtao JackyWay Josh Phillips T5-AndyML huohua-dev imfing Randy Torres Marco Di Dionisio iamadig humanwritten Rob Axelsen Pratham Dubey 0oAstro aaronn Arturo Asleep123 dantelex fcatuhe gtsifrikas hrdwdmrbl hugobarauna jayhickey jiulingyun Jonathan D. Rhyne (DJ-D) jverdi kitze loukotal minghinmatthewlam MSch odrobnik oswalpalash ratulsarna reeltimeapps snopoke sreekaransrinath timkrase

License

MIT © OpenClaw Foundation. See THIRD_PARTY_NOTICES.md for incorporated or adapted code.