{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "OpenClaw Chronicles",
  "home_page_url": "https://openclawchronicles.com",
  "feed_url": "https://openclawchronicles.com/feed.json",
  "description": "OpenClaw Chronicles covers OpenClaw releases, security alerts, migration guides, tutorials, and ecosystem news.",
  "icon": "https://openclawchronicles.com/icon-512.png",
  "favicon": "https://openclawchronicles.com/favicon.png",
  "authors": [
    {
      "name": "Cody",
      "url": "https://openclawchronicles.com/about/",
      "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
    }
  ],
  "language": "en-US",
  "banner_image": "https://openclawchronicles.com/assets/images/about-banner.jpg",
  "hubs": [
    {
      "type": "alternate",
      "url": "https://openclawchronicles.com/feed.xml",
      "mime_type": "application/rss+xml"
    }
  ],
  "items": [
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-9-utf16-truncation-sweep/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-9-utf16-truncation-sweep/",
      "title": "OpenClaw Hardens UTF-16 Truncation Paths",
      "summary": "OpenClaw is replacing raw string slicing in provider, audit, notification, and live-chat truncation paths with safer UTF-16 handling.",
      "content_text": "OpenClaw merged a cluster of small hardening PRs after the July 8 nightly run that all point at the same problem: raw string truncation can split UTF-16 surrogate pairs and leave malformed text behind.\n\nThe most visible item is [PR #102496, \"fix(agents): keep provider error detail truncation UTF-16 safe\"](https://github.com/openclaw/openclaw/pull/102496). Related commits in the same window also covered tool-policy audit fields, Android notification previews, and live chat assistant buffer tails.\n\nIndividually, these are small fixes. Together, they show OpenClaw continuing a broader response-bounding campaign across agent, gateway, channel, and audit surfaces.\n\n## The Bug Pattern\n\nJavaScript strings are UTF-16 sequences. A character outside the basic multilingual plane, such as many emoji, can be represented as a surrogate pair. If code truncates with a raw `.slice(...)` at exactly the wrong boundary, it can keep only half of that pair.\n\nThat dangling surrogate is not just ugly output. It can produce malformed provider previews, confusing logs, broken notification text, or downstream serialization issues in places that expect valid text.\n\nPR #102496 gives the simplest proof. A fixture puts an emoji at the default provider-error truncation boundary. The old implementation leaves a lone surrogate; the new `truncateUtf16Safe` path does not.\n\n## Where OpenClaw Tightened It\n\nThe provider-error fix replaces raw slicing in `src/agents/provider-http-errors.ts` so provider error previews stay valid even when an emoji lands on the edge of the configured limit.\n\nThe same morning window also included:\n\n- [PR #102464](https://github.com/openclaw/openclaw/pull/102464), which applies safe truncation to tool-policy audit field values.\n- [PR #102442](https://github.com/openclaw/openclaw/pull/102442), which keeps forwarded Android notification titles and message previews valid at the 512-code-unit limit.\n- [PR #102484](https://github.com/openclaw/openclaw/pull/102484), which keeps live chat assistant buffer tail truncation UTF-16 safe.\n\nThe surfaces differ, but the safety rule is the same: enforce the byte or character budget without creating invalid text at the boundary.\n\n## Why It Matters\n\nOpenClaw has many bounded-output paths. Provider errors need caps so remote responses cannot flood the UI. Audit fields need caps so records stay readable and predictable. Mobile notifications and live chat buffers need caps so channel surfaces do not overrun their limits.\n\nThose caps are good. The hard part is making sure truncation remains text-aware rather than just index-aware.\n\nThis is especially relevant for a global, chat-heavy assistant runtime. User names, provider errors, messages, notifications, and copied content can include emoji and non-Latin scripts. Safe truncation should be the default behavior in every edge-facing path.\n\n## Validation\n\nPR #102496 reports a focused Vitest run for `provider-http-errors.test.ts` with 14 passing tests. The regression test places an emoji at the default boundary and asserts that the formatted detail contains no lone surrogates.\n\nPR #102442 reports Android notification sanitizer coverage and ktlint passing through a Blacksmith Testbox run. Its proof covers both sides of the boundary: a split pair is removed, while a complete pair ending at the limit is preserved.\n\nThe tool-policy audit PR includes a before-and-after proof showing raw slicing leaving a dangling high surrogate and `truncateUtf16Safe` producing clean output.\n\n## Bottom Line\n\nThis is the kind of hardening that rarely makes a splash but improves the whole system. OpenClaw is replacing brittle truncation with text-aware truncation in more places, which makes provider errors, audit logs, notifications, and chat buffers safer for real-world multilingual input.",
      "content_html": "<p>OpenClaw merged a cluster of small hardening PRs after the July 8 nightly run that all point at the same problem: raw string truncation can split UTF-16 surrogate pairs and leave malformed text behind.</p><p>The most visible item is <a href=\"https://github.com/openclaw/openclaw/pull/102496\">PR #102496, \"fix(agents): keep provider error detail truncation UTF-16 safe\"</a>. Related commits in the same window also covered tool-policy audit fields, Android notification previews, and live chat assistant buffer tails.</p><p>Individually, these are small fixes. Together, they show OpenClaw continuing a broader response-bounding campaign across agent, gateway, channel, and audit surfaces.</p><h2>The Bug Pattern</h2><p>JavaScript strings are UTF-16 sequences. A character outside the basic multilingual plane, such as many emoji, can be represented as a surrogate pair. If code truncates with a raw <code>.slice(...)</code> at exactly the wrong boundary, it can keep only half of that pair.</p><p>That dangling surrogate is not just ugly output. It can produce malformed provider previews, confusing logs, broken notification text, or downstream serialization issues in places that expect valid text.</p><p>PR #102496 gives the simplest proof. A fixture puts an emoji at the default provider-error truncation boundary. The old implementation leaves a lone surrogate; the new <code>truncateUtf16Safe</code> path does not.</p><h2>Where OpenClaw Tightened It</h2><p>The provider-error fix replaces raw slicing in <code>src/agents/provider-http-errors.ts</code> so provider error previews stay valid even when an emoji lands on the edge of the configured limit.</p><p>The same morning window also included:</p><ul><li><a href=\"https://github.com/openclaw/openclaw/pull/102464\">PR #102464</a>, which applies safe truncation to tool-policy audit field values.</li><li><a href=\"https://github.com/openclaw/openclaw/pull/102442\">PR #102442</a>, which keeps forwarded Android notification titles and message previews valid at the 512-code-unit limit.</li><li><a href=\"https://github.com/openclaw/openclaw/pull/102484\">PR #102484</a>, which keeps live chat assistant buffer tail truncation UTF-16 safe.</li></ul><p>The surfaces differ, but the safety rule is the same: enforce the byte or character budget without creating invalid text at the boundary.</p><h2>Why It Matters</h2><p>OpenClaw has many bounded-output paths. Provider errors need caps so remote responses cannot flood the UI. Audit fields need caps so records stay readable and predictable. Mobile notifications and live chat buffers need caps so channel surfaces do not overrun their limits.</p><p>Those caps are good. The hard part is making sure truncation remains text-aware rather than just index-aware.</p><p>This is especially relevant for a global, chat-heavy assistant runtime. User names, provider errors, messages, notifications, and copied content can include emoji and non-Latin scripts. Safe truncation should be the default behavior in every edge-facing path.</p><h2>Validation</h2><p>PR #102496 reports a focused Vitest run for <code>provider-http-errors.test.ts</code> with 14 passing tests. The regression test places an emoji at the default boundary and asserts that the formatted detail contains no lone surrogates.</p><p>PR #102442 reports Android notification sanitizer coverage and ktlint passing through a Blacksmith Testbox run. Its proof covers both sides of the boundary: a split pair is removed, while a complete pair ending at the limit is preserved.</p><p>The tool-policy audit PR includes a before-and-after proof showing raw slicing leaving a dangling high surrogate and <code>truncateUtf16Safe</code> producing clean output.</p><h2>Bottom Line</h2><p>This is the kind of hardening that rarely makes a splash but improves the whole system. OpenClaw is replacing brittle truncation with text-aware truncation in more places, which makes provider errors, audit logs, notifications, and chat buffers safer for real-world multilingual input.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-utf16-truncation-sweep.png\" alt=\"OpenClaw Hardens UTF-16 Truncation Paths\" /></p>",
      "date_published": "2026-07-09T08:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.649Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Hardens",
        "Truncation",
        "Paths"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-utf16-truncation-sweep.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-utf16-truncation-sweep.png",
          "mime_type": "image/png",
          "title": "OpenClaw Hardens UTF-16 Truncation Paths cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-9-mac-launch-at-login/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-9-mac-launch-at-login/",
      "title": "OpenClaw Keeps Mac Login Launch Running",
      "summary": "OpenClaw's macOS app now preserves its launch-at-login job instead of unloading itself during startup state hydration.",
      "content_text": "OpenClaw merged [PR #102465, \"fix(mac): keep launch-at-login app running\"](https://github.com/openclaw/openclaw/pull/102465), a small but practical macOS reliability fix for people who expect OpenClaw to be available immediately after signing in.\n\nThe bug was easy to miss but painful when it happened. When the macOS app launched through its login item, startup state hydration could cause the app to rewrite its launch-agent plist, boot itself out of launchd, exit, and leave no loaded job behind.\n\nIn other words: launch at login could successfully start OpenClaw, then the app could immediately unload the mechanism that was supposed to keep it running.\n\n## What Changed\n\nThe fix changes how the app refreshes its persisted launch-agent plist. It now treats an already-loaded launchd job as active state and avoids the destructive bootout/bootstrap cycle during startup hydration.\n\nThe loaded-state check also queries launchd independently from plist presence. That keeps the normal toggle behavior intact:\n\n- If the user turns launch at login off, OpenClaw can still unload the job.\n- If the user turns it on, OpenClaw can still write and load the job.\n- If the app is already running because launchd started it, startup hydration no longer tears it down.\n\nThat last point is the one users will notice.\n\n## Why It Matters\n\nThe macOS app has become a bigger part of OpenClaw's first-run and daily-use path. Recent releases added automatic local Gateway setup, improved onboarding, and more native control surfaces. Launch-at-login reliability is part of that same story.\n\nA local assistant is only useful if it is actually present when the user expects it. If the app disappears during login, downstream pieces like the local Gateway, dashboard, voice flows, and node connectivity can all feel unreliable even when the deeper runtime is healthy.\n\nPR #102465 narrows the failure to the launch-agent lifecycle and fixes it without changing the user-facing toggle model.\n\n## User Impact\n\nFor Mac users with launch at login enabled, OpenClaw should remain running after startup instead of briefly appearing and then disappearing.\n\nThe PR's before-and-after evidence is concrete. Before the fix, bootstrapping `ai.openclaw.mac` launched the app, but startup hydration rewrote the plist, booted itself out, exited, and left no loaded job. After the fix, a signed release app launched from the same agent stayed in `state = running` with one OpenClaw process and the plist still present.\n\nThere is no new setup step. The change is about preserving the intended state during app startup.\n\n## Validation\n\nThe PR reports seven passing `LaunchAgentManagerTests` through:\n\n```bash\nswift test --package-path apps/macos --filter LaunchAgentManagerTests\n```\n\nIt also reports a clean local autoreview with no accepted or actionable findings.\n\n## Bottom Line\n\nThis is a narrow macOS fix, but it lands in an important place. OpenClaw's native app experience depends on predictable background availability, and launch-at-login should never be a self-canceling path. PR #102465 makes that path behave like users expect.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/102465\">PR #102465, \"fix(mac): keep launch-at-login app running\"</a>, a small but practical macOS reliability fix for people who expect OpenClaw to be available immediately after signing in.</p><p>The bug was easy to miss but painful when it happened. When the macOS app launched through its login item, startup state hydration could cause the app to rewrite its launch-agent plist, boot itself out of launchd, exit, and leave no loaded job behind.</p><p>In other words: launch at login could successfully start OpenClaw, then the app could immediately unload the mechanism that was supposed to keep it running.</p><h2>What Changed</h2><p>The fix changes how the app refreshes its persisted launch-agent plist. It now treats an already-loaded launchd job as active state and avoids the destructive bootout/bootstrap cycle during startup hydration.</p><p>The loaded-state check also queries launchd independently from plist presence. That keeps the normal toggle behavior intact:</p><ul><li>If the user turns launch at login off, OpenClaw can still unload the job.</li><li>If the user turns it on, OpenClaw can still write and load the job.</li><li>If the app is already running because launchd started it, startup hydration no longer tears it down.</li></ul><p>That last point is the one users will notice.</p><h2>Why It Matters</h2><p>The macOS app has become a bigger part of OpenClaw's first-run and daily-use path. Recent releases added automatic local Gateway setup, improved onboarding, and more native control surfaces. Launch-at-login reliability is part of that same story.</p><p>A local assistant is only useful if it is actually present when the user expects it. If the app disappears during login, downstream pieces like the local Gateway, dashboard, voice flows, and node connectivity can all feel unreliable even when the deeper runtime is healthy.</p><p>PR #102465 narrows the failure to the launch-agent lifecycle and fixes it without changing the user-facing toggle model.</p><h2>User Impact</h2><p>For Mac users with launch at login enabled, OpenClaw should remain running after startup instead of briefly appearing and then disappearing.</p><p>The PR's before-and-after evidence is concrete. Before the fix, bootstrapping <code>ai.openclaw.mac</code> launched the app, but startup hydration rewrote the plist, booted itself out, exited, and left no loaded job. After the fix, a signed release app launched from the same agent stayed in <code>state = running</code> with one OpenClaw process and the plist still present.</p><p>There is no new setup step. The change is about preserving the intended state during app startup.</p><h2>Validation</h2><p>The PR reports seven passing <code>LaunchAgentManagerTests</code> through:</p><p>``<code>bash<br />swift test --package-path apps/macos --filter LaunchAgentManagerTests<br /></code>``</p><p>It also reports a clean local autoreview with no accepted or actionable findings.</p><h2>Bottom Line</h2><p>This is a narrow macOS fix, but it lands in an important place. OpenClaw's native app experience depends on predictable background availability, and launch-at-login should never be a self-canceling path. PR #102465 makes that path behave like users expect.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-mac-launch-at-login.png\" alt=\"OpenClaw Keeps Mac Login Launch Running\" /></p>",
      "date_published": "2026-07-09T08:05:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Keeps",
        "Login",
        "Launch",
        "Running"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-mac-launch-at-login.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-mac-launch-at-login.png",
          "mime_type": "image/png",
          "title": "OpenClaw Keeps Mac Login Launch Running cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-9-realtime-auth-boundary/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-9-realtime-auth-boundary/",
      "title": "OpenClaw Fixes Realtime Auth Boundaries",
      "summary": "OpenClaw now requires Platform API keys for Realtime voice and transcription, avoiding failed Codex OAuth fallbacks.",
      "content_text": "OpenClaw merged [PR #102518, \"fix(openai): correct Realtime auth and transcription secrets\"](https://github.com/openclaw/openclaw/pull/102518), a focused OpenAI provider fix for Talk, Voice Call, and streaming transcription flows.\n\nThe issue was an auth-boundary mismatch. OpenAI Realtime voice and streaming transcription were treating Codex OAuth credentials as if they could be used interchangeably with OpenAI Platform API keys. Those tokens were then sent toward public Platform endpoints where they were not valid for the job. The transcription path also used the retired `/v1/realtime/transcription_sessions` endpoint, so even valid credentials could hit a 404.\n\n## What Changed\n\nThe new behavior is stricter: OpenClaw now requires Platform API-key sources for both OpenAI Realtime surfaces. It stops discovering or advertising Codex OAuth as Realtime auth and instead makes the Platform API-key requirement explicit.\n\nThe transcription secret path also moves to the current `/v1/realtime/client_secrets` API shape. That matters because browser-side Realtime and transcription sessions need short-lived client secrets, not a stale endpoint that no longer issues them.\n\nPR #102518 also changes credential precedence. A configured API-key profile is preferred over `OPENAI_API_KEY`, matching the Talk path and preventing an old environment variable from shadowing the profile the operator actually selected.\n\n## Why It Matters\n\nThis is not just a documentation cleanup. OpenClaw has several ways to authenticate with OpenAI-related systems, and they do not all belong to the same trust boundary.\n\nCodex account auth is routed through the ChatGPT/Codex backend. Platform Realtime conversations use the public OpenAI Platform endpoint. Blending those two flows creates confusing failures and can send the wrong kind of credential to the wrong service.\n\nThe PR frames the fix as an auth-owner boundary change rather than a SecretRef transport workaround. That is the right distinction: SecretRefs help with how credentials are stored and resolved, but they cannot make a Codex OAuth token valid for a Platform API that expects a Platform key.\n\n## User Impact\n\nControl UI Talk and Voice Call Realtime should no longer try a doomed OAuth fallback. Users get an actionable Platform API-key requirement instead of a confusing provider failure.\n\nStreaming transcription is also repaired against the current client-secret API. Existing SecretRef-backed Platform keys still resolve only at the network boundary, so operators who already configured Platform credentials through OpenClaw's secret flow should not need to move secrets into plaintext config.\n\nThe PR also bounds 401 errors so provider responses cannot echo credential material back into the UI, which fits the broader July hardening theme around provider responses and secret surfaces.\n\n## Validation\n\nThe PR reports 80 passing tests across three focused OpenAI Realtime suites, plus `pnpm check:changed`. It also includes live OpenAI API proof with a 1Password-backed Platform key:\n\n- The old transcription endpoint returned HTTP 404.\n- The current transcription client-secret request returned HTTP 200.\n- The current Realtime browser client-secret request returned HTTP 200.\n\nOn a live OpenClaw Gateway with a file SecretRef, `talk.client.create` returned the OpenAI WebRTC transport and the current Realtime calls offer URL without exposing the Platform key.\n\n## Bottom Line\n\nOpenClaw's OpenAI integration is separating account auth from Platform auth more clearly. For users, that means fewer mysterious Realtime failures. For operators, it means Realtime voice and transcription now line up with the credential type those public OpenAI APIs actually require.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/102518\">PR #102518, \"fix(openai): correct Realtime auth and transcription secrets\"</a>, a focused OpenAI provider fix for Talk, Voice Call, and streaming transcription flows.</p><p>The issue was an auth-boundary mismatch. OpenAI Realtime voice and streaming transcription were treating Codex OAuth credentials as if they could be used interchangeably with OpenAI Platform API keys. Those tokens were then sent toward public Platform endpoints where they were not valid for the job. The transcription path also used the retired <code>/v1/realtime/transcription_sessions</code> endpoint, so even valid credentials could hit a 404.</p><h2>What Changed</h2><p>The new behavior is stricter: OpenClaw now requires Platform API-key sources for both OpenAI Realtime surfaces. It stops discovering or advertising Codex OAuth as Realtime auth and instead makes the Platform API-key requirement explicit.</p><p>The transcription secret path also moves to the current <code>/v1/realtime/client_secrets</code> API shape. That matters because browser-side Realtime and transcription sessions need short-lived client secrets, not a stale endpoint that no longer issues them.</p><p>PR #102518 also changes credential precedence. A configured API-key profile is preferred over <code>OPENAI_API_KEY</code>, matching the Talk path and preventing an old environment variable from shadowing the profile the operator actually selected.</p><h2>Why It Matters</h2><p>This is not just a documentation cleanup. OpenClaw has several ways to authenticate with OpenAI-related systems, and they do not all belong to the same trust boundary.</p><p>Codex account auth is routed through the ChatGPT/Codex backend. Platform Realtime conversations use the public OpenAI Platform endpoint. Blending those two flows creates confusing failures and can send the wrong kind of credential to the wrong service.</p><p>The PR frames the fix as an auth-owner boundary change rather than a SecretRef transport workaround. That is the right distinction: SecretRefs help with how credentials are stored and resolved, but they cannot make a Codex OAuth token valid for a Platform API that expects a Platform key.</p><h2>User Impact</h2><p>Control UI Talk and Voice Call Realtime should no longer try a doomed OAuth fallback. Users get an actionable Platform API-key requirement instead of a confusing provider failure.</p><p>Streaming transcription is also repaired against the current client-secret API. Existing SecretRef-backed Platform keys still resolve only at the network boundary, so operators who already configured Platform credentials through OpenClaw's secret flow should not need to move secrets into plaintext config.</p><p>The PR also bounds 401 errors so provider responses cannot echo credential material back into the UI, which fits the broader July hardening theme around provider responses and secret surfaces.</p><h2>Validation</h2><p>The PR reports 80 passing tests across three focused OpenAI Realtime suites, plus <code>pnpm check:changed</code>. It also includes live OpenAI API proof with a 1Password-backed Platform key:</p><ul><li>The old transcription endpoint returned HTTP 404.</li><li>The current transcription client-secret request returned HTTP 200.</li><li>The current Realtime browser client-secret request returned HTTP 200.</li></ul><p>On a live OpenClaw Gateway with a file SecretRef, <code>talk.client.create</code> returned the OpenAI WebRTC transport and the current Realtime calls offer URL without exposing the Platform key.</p><h2>Bottom Line</h2><p>OpenClaw's OpenAI integration is separating account auth from Platform auth more clearly. For users, that means fewer mysterious Realtime failures. For operators, it means Realtime voice and transcription now line up with the credential type those public OpenAI APIs actually require.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-realtime-auth-boundary.png\" alt=\"OpenClaw Fixes Realtime Auth Boundaries\" /></p>",
      "date_published": "2026-07-09T08:00:00.000Z",
      "date_modified": "2026-07-09T08:12:14.649Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Fixes",
        "Realtime",
        "Auth",
        "Boundaries"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-realtime-auth-boundary.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-9-realtime-auth-boundary.png",
          "mime_type": "image/png",
          "title": "OpenClaw Fixes Realtime Auth Boundaries cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-exec-approval-hardening/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-exec-approval-hardening/",
      "title": "OpenClaw Hardens Exec Approval Rules",
      "summary": "OpenClaw tightens package-manager approvals, inline eval detection, and jq safe-bin behavior for safer local exec runs.",
      "content_text": "OpenClaw landed a cluster of exec-boundary fixes today: [PR #102035, \"fix: bind package-manager exec approvals to inner commands\"](https://github.com/openclaw/openclaw/pull/102035), [PR #101353, \"fix: detect joined inline eval flags\"](https://github.com/openclaw/openclaw/pull/101353), and [PR #102032, \"Harden jq safe-bin semantics\"](https://github.com/openclaw/openclaw/pull/102032).\n\nThe shared theme is durable trust. When an operator marks a local command as safe or always allowed, OpenClaw has to make sure that approval does not accidentally cover a broader command shape later.\n\n## Package Managers Now Bind to Inner Commands\n\nPR #102035 fixes a package-manager wrapper approval issue. Operators could approve a wrapped exec command as always allowed, but the durable approval could attach to the wrapper rather than the effective inner command.\n\nThe change routes package-manager exec wrappers through the same dispatch-wrapper trust planning used by other command carriers. Supported direct forms bind approval policy to the inner command, while shell-call package-manager forms stay one-shot instead of creating reusable `allow-always` patterns.\n\nThat means common package-manager exec workflows can continue, but a durable approval should no longer broaden trust to later wrapped shell payloads.\n\n## Inline Eval Detection Catches Joined Flags\n\nPR #101353 tightens inline-code detection for interpreters and runtimes. The issue was that joined eval flags could look different from separated flag/value forms, even though they trigger the same kind of inline execution.\n\nOpenClaw now recognizes glued single-letter eval flags such as `-c...` and equals-joined long eval flags such as `--eval=...`. Unrelated multi-letter flags remain exact-only unless their spec declares a prefix form.\n\nFor users with interpreter or runtime binaries in an allowlist, this makes strict inline-eval hardening apply consistently across both separated and joined flag forms.\n\n## jq Leaves Safe Bins\n\nPR #102032 changes how OpenClaw treats `jq` in `tools.exec.safeBins`. Safe bins are intended for narrow stdin-oriented tools whose behavior can be constrained. The PR argues that `jq` is broader than that model because it can read environment data and load code through modules and startup files.\n\nThe result: `jq` no longer qualifies for approval-free safe-bin execution. Operators can still run it through an explicit trusted-path allowlist entry or through the normal approval prompt.\n\nDoctor and security audit now warn about risky `jq` safe-bin entries rather than scaffolding profiles that cannot satisfy the runtime semantic gate.\n\n## Why It Matters\n\nExec controls are one of OpenClaw's sharpest boundaries. Small parser differences can matter when a user expects \"allow this\" to mean a narrow command, not a family of future payloads.\n\nThis set of PRs closes three practical gaps:\n\n- Package-manager approvals bind to the inner command instead of the wrapper.\n- Joined eval flags are treated like separated eval forms.\n- `jq` is removed from the approval-free safe-bin model.\n\nEach change preserves an explicit path for trusted use. What changes is the default treatment of ambiguous or broad command shapes.\n\n## Validation\n\nPR #102035 reports 89 focused tests across wrapper trust planning, allow-always persistence, exec approvals, and node-host run planning.\n\nPR #101353 reports 48 tests for inline eval analysis and exec authorization allowlists.\n\nPR #102032 reports 227 tests across safe-bin semantics, policy, approvals, runtime policy, Doctor integration, security audit, and approval config behavior. It also includes current-head behavior proofs showing unsafe `jq` module and environment probes denied as safe-bin matches, while explicit `/usr/bin/jq` allowlisting and simple `head` safe-bin behavior still work.\n\n## Bottom Line\n\nOpenClaw is tightening exec approval semantics where wrapper commands, interpreter flags, and broadly capable utilities can blur the meaning of \"safe.\" For operators, the safest reading is also the simplest one: durable approvals should apply to the command that will actually run, and broad command surfaces should stay explicit.",
      "content_html": "<p>OpenClaw landed a cluster of exec-boundary fixes today: <a href=\"https://github.com/openclaw/openclaw/pull/102035\">PR #102035, \"fix: bind package-manager exec approvals to inner commands\"</a>, <a href=\"https://github.com/openclaw/openclaw/pull/101353\">PR #101353, \"fix: detect joined inline eval flags\"</a>, and <a href=\"https://github.com/openclaw/openclaw/pull/102032\">PR #102032, \"Harden jq safe-bin semantics\"</a>.</p><p>The shared theme is durable trust. When an operator marks a local command as safe or always allowed, OpenClaw has to make sure that approval does not accidentally cover a broader command shape later.</p><h2>Package Managers Now Bind to Inner Commands</h2><p>PR #102035 fixes a package-manager wrapper approval issue. Operators could approve a wrapped exec command as always allowed, but the durable approval could attach to the wrapper rather than the effective inner command.</p><p>The change routes package-manager exec wrappers through the same dispatch-wrapper trust planning used by other command carriers. Supported direct forms bind approval policy to the inner command, while shell-call package-manager forms stay one-shot instead of creating reusable <code>allow-always</code> patterns.</p><p>That means common package-manager exec workflows can continue, but a durable approval should no longer broaden trust to later wrapped shell payloads.</p><h2>Inline Eval Detection Catches Joined Flags</h2><p>PR #101353 tightens inline-code detection for interpreters and runtimes. The issue was that joined eval flags could look different from separated flag/value forms, even though they trigger the same kind of inline execution.</p><p>OpenClaw now recognizes glued single-letter eval flags such as <code>-c...</code> and equals-joined long eval flags such as <code>--eval=...</code>. Unrelated multi-letter flags remain exact-only unless their spec declares a prefix form.</p><p>For users with interpreter or runtime binaries in an allowlist, this makes strict inline-eval hardening apply consistently across both separated and joined flag forms.</p><h2>jq Leaves Safe Bins</h2><p>PR #102032 changes how OpenClaw treats <code>jq</code> in <code>tools.exec.safeBins</code>. Safe bins are intended for narrow stdin-oriented tools whose behavior can be constrained. The PR argues that <code>jq</code> is broader than that model because it can read environment data and load code through modules and startup files.</p><p>The result: <code>jq</code> no longer qualifies for approval-free safe-bin execution. Operators can still run it through an explicit trusted-path allowlist entry or through the normal approval prompt.</p><p>Doctor and security audit now warn about risky <code>jq</code> safe-bin entries rather than scaffolding profiles that cannot satisfy the runtime semantic gate.</p><h2>Why It Matters</h2><p>Exec controls are one of OpenClaw's sharpest boundaries. Small parser differences can matter when a user expects \"allow this\" to mean a narrow command, not a family of future payloads.</p><p>This set of PRs closes three practical gaps:</p><ul><li>Package-manager approvals bind to the inner command instead of the wrapper.</li><li>Joined eval flags are treated like separated eval forms.</li><li><code>jq</code> is removed from the approval-free safe-bin model.</li></ul><p>Each change preserves an explicit path for trusted use. What changes is the default treatment of ambiguous or broad command shapes.</p><h2>Validation</h2><p>PR #102035 reports 89 focused tests across wrapper trust planning, allow-always persistence, exec approvals, and node-host run planning.</p><p>PR #101353 reports 48 tests for inline eval analysis and exec authorization allowlists.</p><p>PR #102032 reports 227 tests across safe-bin semantics, policy, approvals, runtime policy, Doctor integration, security audit, and approval config behavior. It also includes current-head behavior proofs showing unsafe <code>jq</code> module and environment probes denied as safe-bin matches, while explicit <code>/usr/bin/jq</code> allowlisting and simple <code>head</code> safe-bin behavior still work.</p><h2>Bottom Line</h2><p>OpenClaw is tightening exec approval semantics where wrapper commands, interpreter flags, and broadly capable utilities can blur the meaning of \"safe.\" For operators, the safest reading is also the simplest one: durable approvals should apply to the command that will actually run, and broad command surfaces should stay explicit.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-exec-approval-hardening.png\" alt=\"OpenClaw Hardens Exec Approval Rules\" /></p>",
      "date_published": "2026-07-08T23:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Hardens",
        "Exec",
        "Approval",
        "Rules"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-exec-approval-hardening.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-exec-approval-hardening.png",
          "mime_type": "image/png",
          "title": "OpenClaw Hardens Exec Approval Rules cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-gateway-requester-boundaries/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-gateway-requester-boundaries/",
      "title": "OpenClaw Narrows Gateway Trust Boundaries",
      "summary": "OpenClaw tightens Gateway requester provenance and blocks non-owner chat runs from receiving privileged control tools.",
      "content_text": "OpenClaw merged two P0 Gateway hardening PRs after the morning run: [PR #102031, \"fix: gate Gateway message action requester provenance\"](https://github.com/openclaw/openclaw/pull/102031), and [PR #102030, \"fix: restrict non-owner gateway tool inventory\"](https://github.com/openclaw/openclaw/pull/102030).\n\nTogether, they narrow the trust boundary between public Gateway clients, channel-provided identity, and the privileged control tools an agent can see during a chat-driven run.\n\n## Requester Provenance Is Now Gated\n\nPR #102031 fixes a requester identity issue in `message.action` requests. Before the change, a write-scoped Gateway client could provide requester identity fields and have those fields treated as trusted channel provenance downstream.\n\nThe fix makes requester account and sender provenance behave like other trusted channel-action context. Only full-scope callers can bridge server-injected requester identity through the public RPC boundary.\n\nWrite-scoped clients can still invoke supported message actions. The important change is that caller-supplied requester identity and owner status are stripped before channel dispatch.\n\nThat keeps the normal workflow intact while removing a spoofing path for actions that depend on trusted sender identity.\n\n## Non-Owners Lose Owner-Only Tools\n\nPR #102030 addresses a related tool-inventory problem. Users with explicit non-owner Gateway access could have owner-only Gateway control tools included in chat-driven agent runs.\n\nThe shared agent tool-policy pipeline now treats explicit non-owner sender identity as a hard deny for owner-only Gateway core tools. The rule applies before the final model tool inventory is returned, including inherited tool surfaces for spawned sessions and scheduled follow-up jobs.\n\nThe PR's proof showed owner/admin WebChat runs keeping `cron`, `gateway`, and `nodes`, while explicit non-owner WebChat returned no protected owner-only tools.\n\n## Why This Matters\n\nGateway identity is not just metadata. It determines whether a request is allowed to act like the owner, whether a channel action can trust its requester, and which control tools a model can call.\n\nThese PRs tighten two different stages:\n\n- Input provenance: write-scoped clients cannot spoof trusted requester fields.\n- Tool exposure: explicit non-owner chat turns do not receive owner-only Gateway, scheduler, or node-control tools.\n\nThat combination matters because agent safety is often about preventing privilege from appearing too early. If a non-owner run never receives the tool, the model cannot accidentally or intentionally use it.\n\n## Validation\n\nPR #102031 reports `git diff --check` and 124 passing tests in `src/gateway/server-methods/send.test.ts`.\n\nPR #102030 reports focused tests for agent tool configuration and OpenClaw coding tool creation: 24 tests in `agent-tools-agent-config.test.ts` and 68 tests in `agent-tools.create-openclaw-coding-tools.test.ts`. It also includes a current-head local adapter proof for owner versus non-owner WebChat inventory.\n\nBoth PRs note that remote Testbox validation was attempted but blocked by local environment constraints, so the published evidence is local and focused.\n\n## Bottom Line\n\nOpenClaw's Gateway surface is getting stricter about who can claim identity and who can see privileged tools. For multi-user chat, WebChat, and channel-driven agents, that is exactly the kind of boundary that should be enforced before a model turn begins.",
      "content_html": "<p>OpenClaw merged two P0 Gateway hardening PRs after the morning run: <a href=\"https://github.com/openclaw/openclaw/pull/102031\">PR #102031, \"fix: gate Gateway message action requester provenance\"</a>, and <a href=\"https://github.com/openclaw/openclaw/pull/102030\">PR #102030, \"fix: restrict non-owner gateway tool inventory\"</a>.</p><p>Together, they narrow the trust boundary between public Gateway clients, channel-provided identity, and the privileged control tools an agent can see during a chat-driven run.</p><h2>Requester Provenance Is Now Gated</h2><p>PR #102031 fixes a requester identity issue in <code>message.action</code> requests. Before the change, a write-scoped Gateway client could provide requester identity fields and have those fields treated as trusted channel provenance downstream.</p><p>The fix makes requester account and sender provenance behave like other trusted channel-action context. Only full-scope callers can bridge server-injected requester identity through the public RPC boundary.</p><p>Write-scoped clients can still invoke supported message actions. The important change is that caller-supplied requester identity and owner status are stripped before channel dispatch.</p><p>That keeps the normal workflow intact while removing a spoofing path for actions that depend on trusted sender identity.</p><h2>Non-Owners Lose Owner-Only Tools</h2><p>PR #102030 addresses a related tool-inventory problem. Users with explicit non-owner Gateway access could have owner-only Gateway control tools included in chat-driven agent runs.</p><p>The shared agent tool-policy pipeline now treats explicit non-owner sender identity as a hard deny for owner-only Gateway core tools. The rule applies before the final model tool inventory is returned, including inherited tool surfaces for spawned sessions and scheduled follow-up jobs.</p><p>The PR's proof showed owner/admin WebChat runs keeping <code>cron</code>, <code>gateway</code>, and <code>nodes</code>, while explicit non-owner WebChat returned no protected owner-only tools.</p><h2>Why This Matters</h2><p>Gateway identity is not just metadata. It determines whether a request is allowed to act like the owner, whether a channel action can trust its requester, and which control tools a model can call.</p><p>These PRs tighten two different stages:</p><ul><li>Input provenance: write-scoped clients cannot spoof trusted requester fields.</li><li>Tool exposure: explicit non-owner chat turns do not receive owner-only Gateway, scheduler, or node-control tools.</li></ul><p>That combination matters because agent safety is often about preventing privilege from appearing too early. If a non-owner run never receives the tool, the model cannot accidentally or intentionally use it.</p><h2>Validation</h2><p>PR #102031 reports <code>git diff --check</code> and 124 passing tests in <code>src/gateway/server-methods/send.test.ts</code>.</p><p>PR #102030 reports focused tests for agent tool configuration and OpenClaw coding tool creation: 24 tests in <code>agent-tools-agent-config.test.ts</code> and 68 tests in <code>agent-tools.create-openclaw-coding-tools.test.ts</code>. It also includes a current-head local adapter proof for owner versus non-owner WebChat inventory.</p><p>Both PRs note that remote Testbox validation was attempted but blocked by local environment constraints, so the published evidence is local and focused.</p><h2>Bottom Line</h2><p>OpenClaw's Gateway surface is getting stricter about who can claim identity and who can see privileged tools. For multi-user chat, WebChat, and channel-driven agents, that is exactly the kind of boundary that should be enforced before a model turn begins.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-gateway-requester-boundaries.png\" alt=\"OpenClaw Narrows Gateway Trust Boundaries\" /></p>",
      "date_published": "2026-07-08T23:05:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Narrows",
        "Gateway",
        "Trust",
        "Boundaries"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-gateway-requester-boundaries.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-gateway-requester-boundaries.png",
          "mime_type": "image/png",
          "title": "OpenClaw Narrows Gateway Trust Boundaries cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-secret-sentinel-egress/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-secret-sentinel-egress/",
      "title": "OpenClaw Adds Secret Sentinel Egress",
      "summary": "OpenClaw now keeps SecretRef-backed model credentials as process-local sentinels until guarded provider egress.",
      "content_text": "OpenClaw merged [PR #102009, \"feat(secrets): egress-time credential injection with process-local sentinels\"](https://github.com/openclaw/openclaw/pull/102009), a P0 security-boundary change aimed at reducing how far provider credentials travel inside the runtime.\n\nThe problem is subtle but important. SecretRefs already keep provider keys out of `openclaw.json`, but once a key is resolved, plaintext can still move through auth storage, stream options, SDK client configuration, logs, debug captures, and error objects. PR #102009 moves OpenClaw toward a narrower model: hold opaque sentinel values through most of that path, then substitute the real credential at guarded provider egress.\n\n## What Changed\n\nThe new flow turns SecretRef-managed model credentials into process-local sentinel strings during model-auth resolution. Those sentinel values are what auth storage, stream options, SDK config, logs, and error paths see.\n\nAt the final outbound provider request boundary, OpenClaw's guarded model fetch substitutes known sentinels in headers and supported URL auth shapes immediately before the SSRF-guarded send. If a value looks like a sentinel but was not registered by the current process, it fails closed before network activity.\n\nThe PR also adds an exact-value redaction registry. Resolved secret values and their percent-encoded forms are registered for masking by the runtime's redaction paths, adding a second layer of protection if plaintext ever reaches a log-like surface.\n\n## Provider Adapter Coverage\n\nThe implementation also tightens adapter behavior across the provider stack. The PR says Anthropic, OpenAI responses and completions, Azure, and Mistral now use SDK-supported custom fetch hooks or HTTP client fetchers.\n\nGoogle Gemini and Google Vertex are handled differently because the installed `@google/genai` path does not expose the same fetch hook. For those, OpenClaw unwraps at construction through an inert host port. In-house transports and plugin-stream handoffs use core-owned unwrap points.\n\nThat matters because a sentinel design only works when every model-call path has a known place to swap the sentinel for the real credential.\n\n## User Impact\n\nFor operators, the headline is simple: no configuration change is required. SecretRef-backed model credentials in auth profiles and model-provider API key paths are protected automatically.\n\nThe PR also documents an incident-response kill switch, `OPENCLAW_SECRET_SENTINELS=off|0|false`. Exact-value redaction remains active even when that switch disables sentinel injection.\n\nThe boundary is intentionally specific. Plain environment credentials without SecretRefs are unchanged, and same-process memory still contains the secret at the final adapter boundary. Channel tokens, MCP headers, skill environment variables, and sandbox egress proxying are listed as follow-up areas rather than part of this PR.\n\n## Validation\n\nThe evidence is unusually broad for a secrets change. The PR reports focused Vitest coverage for sentinel behavior, logging redaction, and provider transport fetch behavior, plus a larger matrix of 900-plus tests, a build, and `pnpm check:changed`.\n\nIt also includes a live-path proof: an isolated OpenClaw home and state directory used an Anthropic API key stored as a file SecretRef, completed a local model call, and then found the raw key only in the staged key file. The debug log, generated model metadata, session files, trajectory files, and state artifacts had zero occurrences.\n\n## Bottom Line\n\nSecretRefs are more useful when plaintext does not become the runtime's default credential representation after resolution. PR #102009 makes the guarded egress boundary the place where model credentials become real again, which is the right direction for a system that increasingly runs agents across logs, captures, providers, and long-lived sessions.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/102009\">PR #102009, \"feat(secrets): egress-time credential injection with process-local sentinels\"</a>, a P0 security-boundary change aimed at reducing how far provider credentials travel inside the runtime.</p><p>The problem is subtle but important. SecretRefs already keep provider keys out of <code>openclaw.json</code>, but once a key is resolved, plaintext can still move through auth storage, stream options, SDK client configuration, logs, debug captures, and error objects. PR #102009 moves OpenClaw toward a narrower model: hold opaque sentinel values through most of that path, then substitute the real credential at guarded provider egress.</p><h2>What Changed</h2><p>The new flow turns SecretRef-managed model credentials into process-local sentinel strings during model-auth resolution. Those sentinel values are what auth storage, stream options, SDK config, logs, and error paths see.</p><p>At the final outbound provider request boundary, OpenClaw's guarded model fetch substitutes known sentinels in headers and supported URL auth shapes immediately before the SSRF-guarded send. If a value looks like a sentinel but was not registered by the current process, it fails closed before network activity.</p><p>The PR also adds an exact-value redaction registry. Resolved secret values and their percent-encoded forms are registered for masking by the runtime's redaction paths, adding a second layer of protection if plaintext ever reaches a log-like surface.</p><h2>Provider Adapter Coverage</h2><p>The implementation also tightens adapter behavior across the provider stack. The PR says Anthropic, OpenAI responses and completions, Azure, and Mistral now use SDK-supported custom fetch hooks or HTTP client fetchers.</p><p>Google Gemini and Google Vertex are handled differently because the installed <code>@google/genai</code> path does not expose the same fetch hook. For those, OpenClaw unwraps at construction through an inert host port. In-house transports and plugin-stream handoffs use core-owned unwrap points.</p><p>That matters because a sentinel design only works when every model-call path has a known place to swap the sentinel for the real credential.</p><h2>User Impact</h2><p>For operators, the headline is simple: no configuration change is required. SecretRef-backed model credentials in auth profiles and model-provider API key paths are protected automatically.</p><p>The PR also documents an incident-response kill switch, <code>OPENCLAW_SECRET_SENTINELS=off|0|false</code>. Exact-value redaction remains active even when that switch disables sentinel injection.</p><p>The boundary is intentionally specific. Plain environment credentials without SecretRefs are unchanged, and same-process memory still contains the secret at the final adapter boundary. Channel tokens, MCP headers, skill environment variables, and sandbox egress proxying are listed as follow-up areas rather than part of this PR.</p><h2>Validation</h2><p>The evidence is unusually broad for a secrets change. The PR reports focused Vitest coverage for sentinel behavior, logging redaction, and provider transport fetch behavior, plus a larger matrix of 900-plus tests, a build, and <code>pnpm check:changed</code>.</p><p>It also includes a live-path proof: an isolated OpenClaw home and state directory used an Anthropic API key stored as a file SecretRef, completed a local model call, and then found the raw key only in the staged key file. The debug log, generated model metadata, session files, trajectory files, and state artifacts had zero occurrences.</p><h2>Bottom Line</h2><p>SecretRefs are more useful when plaintext does not become the runtime's default credential representation after resolution. PR #102009 makes the guarded egress boundary the place where model credentials become real again, which is the right direction for a system that increasingly runs agents across logs, captures, providers, and long-lived sessions.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-secret-sentinel-egress.png\" alt=\"OpenClaw Adds Secret Sentinel Egress\" /></p>",
      "date_published": "2026-07-08T23:00:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Memory",
        "Local Models",
        "Adds",
        "Secret",
        "Sentinel",
        "Egress"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-secret-sentinel-egress.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-secret-sentinel-egress.png",
          "mime_type": "image/png",
          "title": "OpenClaw Adds Secret Sentinel Egress cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-claw-dry-run-provenance/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-claw-dry-run-provenance/",
      "title": "OpenClaw Previews Safer Claw Installs",
      "summary": "OpenClaw Claw plans now preview artifacts, provenance, consent, and rollback actions before any install mutates state.",
      "content_text": "OpenClaw merged two related Claw lifecycle PRs just after the nightly cutoff: [PR #101842, \"Add Claw artifact provenance preview\"](https://github.com/openclaw/openclaw/pull/101842), and [PR #101874, \"Add Claw dry-run apply lifecycle plan\"](https://github.com/openclaw/openclaw/pull/101874).\n\nTogether, they move Claws closer to an install flow where operators can inspect what will happen before anything changes on disk, in automation, or in Gateway state.\n\n## Artifact and Provenance Preview\n\nPR #101842 adds artifact preview metadata to the existing read-only Claw plan output. It reuses OpenClaw's canonical selector parsers for `clawhub:`, `npm:`, git, file/local, and npm-pack style selectors.\n\nThe plan can now describe the expected install surface and provenance family for entries such as:\n\n- Skills\n- Plugins\n- MCP servers\n- Connectors\n\nUnsupported package selector shapes are marked as blocked in the read-only plan. The PR is explicit about what it does not do: there is no artifact fetch, install, workspace mutation, automation enablement, provenance write, or Gateway state change.\n\nThat makes the feature a preview slice, not an installer.\n\n## Dry-Run Apply Plans\n\nPR #101874 builds on that preview with `openclaw.clawApplyPlan.v1`, a dry-run apply lifecycle plan derived from the read-only Claw plan.\n\nIt adds:\n\n- `openclaw claws apply <manifest> --dry-run`\n- `openclaw claws feed apply <feed> <claw> --dry-run`\n\nThe dry-run plan models install actions, consent-required workspace or automation actions, provenance records, rollback actions, and required-entry blockers. It still refuses real apply unless `--dry-run` is provided.\n\nThe PR's observed summaries show a five-entry plan with five install actions, two consent-required entries, zero blocked entries, five provenance records, and five rollback actions.\n\n## Why It Matters\n\nClaws are meant to bundle useful agent capabilities, but capability bundles are also a trust boundary. A manifest may ask for packages, workspace files, scheduled automations, or other pieces that affect how an agent behaves.\n\nPreviewing the install surface before mutation gives operators a way to ask better questions:\n\n- Which package sources are involved?\n- Which entries require explicit consent?\n- What provenance records would be created?\n- What rollback actions would exist?\n- Which required entries block the plan?\n\nThat is the right shape for a feature that may eventually install skills, plugins, MCP servers, connectors, workspace files, and automations from a feed.\n\n## Validation\n\nBoth PRs report focused Vitest coverage across Claw schema, feed, CLI, plugin install config, command registry, and root command descriptions. They also report `git diff --check` and conflict-marker checks.\n\nPR #101842 includes a real read-only feed-plan proof against an isolated state directory. PR #101874 includes dry-run JSON proofs for both direct manifest apply and feed apply paths, with `mutationAllowed` set to `false`.\n\n## Bottom Line\n\nOpenClaw is adding the inspection layer before the install layer. Claw operators can now see more of the artifact, provenance, consent, and rollback shape before any future apply flow gets permission to mutate state.",
      "content_html": "<p>OpenClaw merged two related Claw lifecycle PRs just after the nightly cutoff: <a href=\"https://github.com/openclaw/openclaw/pull/101842\">PR #101842, \"Add Claw artifact provenance preview\"</a>, and <a href=\"https://github.com/openclaw/openclaw/pull/101874\">PR #101874, \"Add Claw dry-run apply lifecycle plan\"</a>.</p><p>Together, they move Claws closer to an install flow where operators can inspect what will happen before anything changes on disk, in automation, or in Gateway state.</p><h2>Artifact and Provenance Preview</h2><p>PR #101842 adds artifact preview metadata to the existing read-only Claw plan output. It reuses OpenClaw's canonical selector parsers for <code>clawhub:</code>, <code>npm:</code>, git, file/local, and npm-pack style selectors.</p><p>The plan can now describe the expected install surface and provenance family for entries such as:</p><ul><li>Skills</li><li>Plugins</li><li>MCP servers</li><li>Connectors</li></ul><p>Unsupported package selector shapes are marked as blocked in the read-only plan. The PR is explicit about what it does not do: there is no artifact fetch, install, workspace mutation, automation enablement, provenance write, or Gateway state change.</p><p>That makes the feature a preview slice, not an installer.</p><h2>Dry-Run Apply Plans</h2><p>PR #101874 builds on that preview with <code>openclaw.clawApplyPlan.v1</code>, a dry-run apply lifecycle plan derived from the read-only Claw plan.</p><p>It adds:</p><ul><li><code>openclaw claws apply <manifest> --dry-run</code></li><li><code>openclaw claws feed apply <feed> <claw> --dry-run</code></li></ul><p>The dry-run plan models install actions, consent-required workspace or automation actions, provenance records, rollback actions, and required-entry blockers. It still refuses real apply unless <code>--dry-run</code> is provided.</p><p>The PR's observed summaries show a five-entry plan with five install actions, two consent-required entries, zero blocked entries, five provenance records, and five rollback actions.</p><h2>Why It Matters</h2><p>Claws are meant to bundle useful agent capabilities, but capability bundles are also a trust boundary. A manifest may ask for packages, workspace files, scheduled automations, or other pieces that affect how an agent behaves.</p><p>Previewing the install surface before mutation gives operators a way to ask better questions:</p><ul><li>Which package sources are involved?</li><li>Which entries require explicit consent?</li><li>What provenance records would be created?</li><li>What rollback actions would exist?</li><li>Which required entries block the plan?</li></ul><p>That is the right shape for a feature that may eventually install skills, plugins, MCP servers, connectors, workspace files, and automations from a feed.</p><h2>Validation</h2><p>Both PRs report focused Vitest coverage across Claw schema, feed, CLI, plugin install config, command registry, and root command descriptions. They also report <code>git diff --check</code> and conflict-marker checks.</p><p>PR #101842 includes a real read-only feed-plan proof against an isolated state directory. PR #101874 includes dry-run JSON proofs for both direct manifest apply and feed apply paths, with <code>mutationAllowed</code> set to <code>false</code>.</p><h2>Bottom Line</h2><p>OpenClaw is adding the inspection layer before the install layer. Claw operators can now see more of the artifact, provenance, consent, and rollback shape before any future apply flow gets permission to mutate state.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-claw-dry-run-provenance.png\" alt=\"OpenClaw Previews Safer Claw Installs\" /></p>",
      "date_published": "2026-07-08T08:30:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "Previews",
        "Safer",
        "Claw",
        "Installs"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-claw-dry-run-provenance.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-claw-dry-run-provenance.png",
          "mime_type": "image/png",
          "title": "OpenClaw Previews Safer Claw Installs cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-voice-call-agent-routing/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-voice-call-agent-routing/",
      "title": "OpenClaw Preserves Voice Call Agent Routing",
      "summary": "OpenClaw voice and Google Meet sessions now keep the invoking agent fixed across Gateway and realtime call paths.",
      "content_text": "OpenClaw merged [PR #77763, \"fix(voice-call): preserve per-call agent routing\"](https://github.com/openclaw/openclaw/pull/77763), a P1 routing fix for Google Meet and direct Voice Call sessions in multi-agent installations.\n\nThe bug was subtle but serious: a call could lose the invoking agent at tool and Gateway boundaries. That meant voice sessions could speak, transcribe, or consult as the configured default agent instead of the agent that actually started the call.\n\n## What Changed\n\nAgent identity is now resolved once when a call is created and frozen on the call record. Response generation, realtime instructions, realtime consults, Google Meet transports, and Voice Call actions all consume that same canonical identity.\n\nFor Google Meet, the PR uses a constrained trusted in-process Gateway runtime for per-agent dispatch. The PR also draws a clear boundary around spoofing and ambiguity:\n\n- External callers cannot spoof `agentId`.\n- Explicit remote Gateway URLs remain authoritative.\n- Ambiguous non-default-agent remote or standalone routing fails closed.\n- Main-agent and explicitly configured remote Gateway behavior remains supported.\n\nThe important part is that OpenClaw now prefers an actionable routing error over silently falling back to the wrong agent.\n\n## Why It Matters\n\nVoice and meeting integrations are high-context surfaces. They can involve live conversation, transcription, realtime instructions, and tool-backed consultation. In a multi-agent setup, the difference between \"the agent that started this call\" and \"the default agent\" can be the difference between the right workspace, memory, permissions, and persona.\n\nIf a call leaks into the default agent, the user may hear an answer from the wrong context. In the worst case, the wrong agent could consult data or tools that were not intended for that call.\n\nThis PR treats per-call agent identity as session state that must survive the whole route, not a hint that can be recomputed differently in each layer.\n\n## User Impact\n\nFor operators running multiple agents, concurrent users should now hear and consult with the agent that initiated each call. Google Meet Chrome, Chrome-node, and Voice Call transports should preserve the same agent for the full session.\n\nMisconfigured non-default-agent routing should produce a clearer error instead of quietly crossing into another agent's context.\n\n## Validation\n\nThe PR reports a focused Blacksmith Testbox suite with 323 tests passing across Gateway, plugin registry, Voice Call, and Google Meet. It also reports `pnpm check:changed`, a full `pnpm build`, and a fresh structured autoreview with no accepted actionable findings.\n\nThe hosted proof is linked from the PR at [GitHub Actions run 28870210067](https://github.com/openclaw/openclaw/actions/runs/28870210067).\n\n## Bottom Line\n\nOpenClaw voice sessions now have a stronger identity boundary. Calls should stay attached to the agent that created them, and uncertain routes should fail visibly instead of borrowing the default agent.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/77763\">PR #77763, \"fix(voice-call): preserve per-call agent routing\"</a>, a P1 routing fix for Google Meet and direct Voice Call sessions in multi-agent installations.</p><p>The bug was subtle but serious: a call could lose the invoking agent at tool and Gateway boundaries. That meant voice sessions could speak, transcribe, or consult as the configured default agent instead of the agent that actually started the call.</p><h2>What Changed</h2><p>Agent identity is now resolved once when a call is created and frozen on the call record. Response generation, realtime instructions, realtime consults, Google Meet transports, and Voice Call actions all consume that same canonical identity.</p><p>For Google Meet, the PR uses a constrained trusted in-process Gateway runtime for per-agent dispatch. The PR also draws a clear boundary around spoofing and ambiguity:</p><ul><li>External callers cannot spoof <code>agentId</code>.</li><li>Explicit remote Gateway URLs remain authoritative.</li><li>Ambiguous non-default-agent remote or standalone routing fails closed.</li><li>Main-agent and explicitly configured remote Gateway behavior remains supported.</li></ul><p>The important part is that OpenClaw now prefers an actionable routing error over silently falling back to the wrong agent.</p><h2>Why It Matters</h2><p>Voice and meeting integrations are high-context surfaces. They can involve live conversation, transcription, realtime instructions, and tool-backed consultation. In a multi-agent setup, the difference between \"the agent that started this call\" and \"the default agent\" can be the difference between the right workspace, memory, permissions, and persona.</p><p>If a call leaks into the default agent, the user may hear an answer from the wrong context. In the worst case, the wrong agent could consult data or tools that were not intended for that call.</p><p>This PR treats per-call agent identity as session state that must survive the whole route, not a hint that can be recomputed differently in each layer.</p><h2>User Impact</h2><p>For operators running multiple agents, concurrent users should now hear and consult with the agent that initiated each call. Google Meet Chrome, Chrome-node, and Voice Call transports should preserve the same agent for the full session.</p><p>Misconfigured non-default-agent routing should produce a clearer error instead of quietly crossing into another agent's context.</p><h2>Validation</h2><p>The PR reports a focused Blacksmith Testbox suite with 323 tests passing across Gateway, plugin registry, Voice Call, and Google Meet. It also reports <code>pnpm check:changed</code>, a full <code>pnpm build</code>, and a fresh structured autoreview with no accepted actionable findings.</p><p>The hosted proof is linked from the PR at <a href=\"https://github.com/openclaw/openclaw/actions/runs/28870210067\">GitHub Actions run 28870210067</a>.</p><h2>Bottom Line</h2><p>OpenClaw voice sessions now have a stronger identity boundary. Calls should stay attached to the agent that created them, and uncertain routes should fail visibly instead of borrowing the default agent.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-voice-call-agent-routing.png\" alt=\"OpenClaw Preserves Voice Call Agent Routing\" /></p>",
      "date_published": "2026-07-08T08:20:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Memory",
        "Preserves",
        "Voice",
        "Call",
        "Agent",
        "Routing"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-voice-call-agent-routing.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-voice-call-agent-routing.png",
          "mime_type": "image/png",
          "title": "OpenClaw Preserves Voice Call Agent Routing cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-8-first-run-onboarding/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-8-first-run-onboarding/",
      "title": "OpenClaw Fixes First-Run Onboarding",
      "summary": "OpenClaw fresh installs now enter onboarding before gateway probes, preventing missing auth, config, and service state.",
      "content_text": "OpenClaw merged [PR #101901, \"fix(installer): complete first-run onboarding\"](https://github.com/openclaw/openclaw/pull/101901), a P0 installer fix for fresh git installs that could otherwise report success before the system was actually ready to run.\n\nThe PR moves new installs into onboarding before Doctor checks or Gateway finalization probes. That ordering matters because onboarding is the step that creates the first-run configuration, persists Gateway authentication, and prepares managed service state.\n\n## What Broke\n\nThe PR describes a fresh install path that could finish without creating `~/.openclaw/openclaw.json`, Gateway authentication, or a managed Gateway service. Follow-up commands then failed twice: first because the user's shell could still resolve an old `/usr/bin/openclaw` path, and then because the new install still lacked gateway mode, auth, and service state.\n\nThe Control TUI could also fail with `Missing gateway auth token` because setup had never completed the authentication step.\n\nThat is a rough first experience for new operators. A successful install should leave the next command usable, not send the user straight into missing-token and stale-PATH failures.\n\n## What Changed\n\nThe installer now treats first-run onboarding as the finalization path for fresh installs. In practice, that means:\n\n- Fresh installs enter onboarding before Doctor or Gateway health probes.\n- Follow-up commands use the just-installed OpenClaw binary.\n- The installer explains `hash -r` when a shell is still caching a removed binary path.\n- Onboarding persists Gateway configuration and authentication before the managed service is installed or started.\n- Configured upgrades keep their existing Doctor, plugin update, Gateway restart, and dashboard behavior.\n\nThat last point is important. The PR does not replace upgrade health checks with onboarding. It separates the fresh-install path from the already-configured upgrade path.\n\n## Why It Matters\n\nOpenClaw installations often include local services, auth files, gateway mode, shell paths, and optional managed service startup. If those steps happen in the wrong order, a command can look like it installed cleanly while leaving the operator with an unusable runtime.\n\nThis fix makes first-run setup more honest. New installs should complete the state they need before later health probes decide whether the environment is configured.\n\nIt also makes stale shell path behavior less mysterious. Users who recently removed or replaced an `openclaw` binary can get a concrete explanation instead of chasing a command that points at the wrong location.\n\n## Validation\n\nThe PR reports 61 passing installer regression tests through `node scripts/run-vitest.mjs test/scripts/install-sh.test.ts`, plus `bash -n scripts/install.sh`, `git diff --check`, and a clean structured autoreview.\n\nThe real-behavior proof covers fresh-install onboarding, configured-upgrade Doctor behavior, stale PATH handling, no-TTY guidance, Gateway finalization ordering, and successful-upgrade dashboard behavior.\n\nThe author also notes one boundary clearly: an isolated black-box fresh install was terminated after dependency installation continued beyond 23 minutes, so the PR does not claim a completed full fresh-VPS artifact.\n\n## Bottom Line\n\nOpenClaw fresh installs should now finish through onboarding instead of skipping the state that makes the first real command work. For new users, that should turn a brittle install-success message into a more complete setup path.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101901\">PR #101901, \"fix(installer): complete first-run onboarding\"</a>, a P0 installer fix for fresh git installs that could otherwise report success before the system was actually ready to run.</p><p>The PR moves new installs into onboarding before Doctor checks or Gateway finalization probes. That ordering matters because onboarding is the step that creates the first-run configuration, persists Gateway authentication, and prepares managed service state.</p><h2>What Broke</h2><p>The PR describes a fresh install path that could finish without creating <code>~/.openclaw/openclaw.json</code>, Gateway authentication, or a managed Gateway service. Follow-up commands then failed twice: first because the user's shell could still resolve an old <code>/usr/bin/openclaw</code> path, and then because the new install still lacked gateway mode, auth, and service state.</p><p>The Control TUI could also fail with <code>Missing gateway auth token</code> because setup had never completed the authentication step.</p><p>That is a rough first experience for new operators. A successful install should leave the next command usable, not send the user straight into missing-token and stale-PATH failures.</p><h2>What Changed</h2><p>The installer now treats first-run onboarding as the finalization path for fresh installs. In practice, that means:</p><ul><li>Fresh installs enter onboarding before Doctor or Gateway health probes.</li><li>Follow-up commands use the just-installed OpenClaw binary.</li><li>The installer explains <code>hash -r</code> when a shell is still caching a removed binary path.</li><li>Onboarding persists Gateway configuration and authentication before the managed service is installed or started.</li><li>Configured upgrades keep their existing Doctor, plugin update, Gateway restart, and dashboard behavior.</li></ul><p>That last point is important. The PR does not replace upgrade health checks with onboarding. It separates the fresh-install path from the already-configured upgrade path.</p><h2>Why It Matters</h2><p>OpenClaw installations often include local services, auth files, gateway mode, shell paths, and optional managed service startup. If those steps happen in the wrong order, a command can look like it installed cleanly while leaving the operator with an unusable runtime.</p><p>This fix makes first-run setup more honest. New installs should complete the state they need before later health probes decide whether the environment is configured.</p><p>It also makes stale shell path behavior less mysterious. Users who recently removed or replaced an <code>openclaw</code> binary can get a concrete explanation instead of chasing a command that points at the wrong location.</p><h2>Validation</h2><p>The PR reports 61 passing installer regression tests through <code>node scripts/run-vitest.mjs test/scripts/install-sh.test.ts</code>, plus <code>bash -n scripts/install.sh</code>, <code>git diff --check</code>, and a clean structured autoreview.</p><p>The real-behavior proof covers fresh-install onboarding, configured-upgrade Doctor behavior, stale PATH handling, no-TTY guidance, Gateway finalization ordering, and successful-upgrade dashboard behavior.</p><p>The author also notes one boundary clearly: an isolated black-box fresh install was terminated after dependency installation continued beyond 23 minutes, so the PR does not claim a completed full fresh-VPS artifact.</p><h2>Bottom Line</h2><p>OpenClaw fresh installs should now finish through onboarding instead of skipping the state that makes the first real command work. For new users, that should turn a brittle install-success message into a more complete setup path.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-first-run-onboarding.png\" alt=\"OpenClaw Fixes First-Run Onboarding\" /></p>",
      "date_published": "2026-07-08T08:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Guides",
        "Fixes",
        "First",
        "Onboarding"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-first-run-onboarding.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-8-first-run-onboarding.png",
          "mime_type": "image/png",
          "title": "OpenClaw Fixes First-Run Onboarding cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-policy-doctor-endpoint-repair/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-policy-doctor-endpoint-repair/",
      "title": "OpenClaw Doctor Can Repair Denied Gateway Endpoints",
      "summary": "OpenClaw Policy doctor can now auto-disable denied Gateway HTTP endpoints while preserving nested URL-fetch options.",
      "content_text": "OpenClaw merged [PR #99731, \"policy: repair denied gateway http endpoints\"](https://github.com/openclaw/openclaw/pull/99731), extending `doctor --fix` so Policy can automatically repair one class of Gateway HTTP endpoint findings.\n\nThe new repair is intentionally narrow: when Policy reports denied Gateway HTTP endpoints that are still enabled, `doctor --fix` can set the exact reported `enabled` paths to `false`.\n\n## What Changed\n\nThe Policy doctor check `policy/gateway-http-endpoint-enabled` is now classified as an automatic narrowing repair. When workspace repairs are enabled, OpenClaw can disable the denied endpoint leaves named by the finding.\n\nThe PR's proof case uses two Gateway endpoints:\n\n- `gateway.http.endpoints.chatCompletions.enabled`\n- `gateway.http.endpoints.responses.enabled`\n\nWith both endpoints denied by policy, `doctor --fix` disables those two `enabled` values and validates that the findings are gone.\n\n## What It Does Not Change\n\nThe repair does not rewrite the entire endpoint object. That matters because endpoint config can contain nested options such as URL-fetch settings.\n\nIn the PR proof, nested values like `images.allowUrl`, `files.allowUrl`, and `images.urlAllowlist` survive the repair. OpenClaw turns the endpoint off, but it does not discard the operator's detailed configuration.\n\nThe PR also keeps URL-fetch allowlist findings manual. This change only disables denied endpoints; it does not try to infer safe allowlists.\n\n## Why It Matters\n\nGateway HTTP endpoints are powerful surfaces. If an operator's Policy configuration says an endpoint is denied, leaving that endpoint enabled is a security-boundary mismatch.\n\nBefore this change, Doctor could identify the problem but still require manual editing. That is fine for careful operators, but it creates extra toil and leaves room for partial or incorrect fixes.\n\nThis PR makes the safe repair path available directly through `doctor --fix`: disable the endpoint that Policy says should not be exposed, then validate that the finding cleared.\n\n## Safety Shape\n\nThe repair is a narrowing action, not an expansion. It turns access off. It does not loosen allowlists, create new endpoints, or enable alternate behavior.\n\nThat makes it a good candidate for automatic workspace repair. The action aligns the OpenClaw config with the stricter Policy requirement and leaves more ambiguous policy work in the operator's hands.\n\n## Validation\n\nThe PR reports a real proof against an isolated temp workspace using the actual Policy doctor registration plus `runDoctorHealthRepairs`. The proof ran one check, repaired two findings, validated one check, and ended with zero remaining endpoint findings.\n\nSupporting validation included a focused Vitest shard with 2 files and 299 tests passing, `pnpm docs:map:check`, formatting checks for touched docs and policy files, and clean `git diff --check` output.\n\nNo live Gateway server, provider call, network URL-fetch, or LLM call was involved in the proof, which is appropriate for a config repair path.\n\n## Bottom Line\n\nOpenClaw Doctor can now close a concrete Policy gap for Gateway HTTP endpoints. When an endpoint is denied, `doctor --fix` can disable it precisely while keeping the rest of the endpoint configuration intact.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99731\">PR #99731, \"policy: repair denied gateway http endpoints\"</a>, extending <code>doctor --fix</code> so Policy can automatically repair one class of Gateway HTTP endpoint findings.</p><p>The new repair is intentionally narrow: when Policy reports denied Gateway HTTP endpoints that are still enabled, <code>doctor --fix</code> can set the exact reported <code>enabled</code> paths to <code>false</code>.</p><h2>What Changed</h2><p>The Policy doctor check <code>policy/gateway-http-endpoint-enabled</code> is now classified as an automatic narrowing repair. When workspace repairs are enabled, OpenClaw can disable the denied endpoint leaves named by the finding.</p><p>The PR's proof case uses two Gateway endpoints:</p><ul><li><code>gateway.http.endpoints.chatCompletions.enabled</code></li><li><code>gateway.http.endpoints.responses.enabled</code></li></ul><p>With both endpoints denied by policy, <code>doctor --fix</code> disables those two <code>enabled</code> values and validates that the findings are gone.</p><h2>What It Does Not Change</h2><p>The repair does not rewrite the entire endpoint object. That matters because endpoint config can contain nested options such as URL-fetch settings.</p><p>In the PR proof, nested values like <code>images.allowUrl</code>, <code>files.allowUrl</code>, and <code>images.urlAllowlist</code> survive the repair. OpenClaw turns the endpoint off, but it does not discard the operator's detailed configuration.</p><p>The PR also keeps URL-fetch allowlist findings manual. This change only disables denied endpoints; it does not try to infer safe allowlists.</p><h2>Why It Matters</h2><p>Gateway HTTP endpoints are powerful surfaces. If an operator's Policy configuration says an endpoint is denied, leaving that endpoint enabled is a security-boundary mismatch.</p><p>Before this change, Doctor could identify the problem but still require manual editing. That is fine for careful operators, but it creates extra toil and leaves room for partial or incorrect fixes.</p><p>This PR makes the safe repair path available directly through <code>doctor --fix</code>: disable the endpoint that Policy says should not be exposed, then validate that the finding cleared.</p><h2>Safety Shape</h2><p>The repair is a narrowing action, not an expansion. It turns access off. It does not loosen allowlists, create new endpoints, or enable alternate behavior.</p><p>That makes it a good candidate for automatic workspace repair. The action aligns the OpenClaw config with the stricter Policy requirement and leaves more ambiguous policy work in the operator's hands.</p><h2>Validation</h2><p>The PR reports a real proof against an isolated temp workspace using the actual Policy doctor registration plus <code>runDoctorHealthRepairs</code>. The proof ran one check, repaired two findings, validated one check, and ended with zero remaining endpoint findings.</p><p>Supporting validation included a focused Vitest shard with 2 files and 299 tests passing, <code>pnpm docs:map:check</code>, formatting checks for touched docs and policy files, and clean <code>git diff --check</code> output.</p><p>No live Gateway server, provider call, network URL-fetch, or LLM call was involved in the proof, which is appropriate for a config repair path.</p><h2>Bottom Line</h2><p>OpenClaw Doctor can now close a concrete Policy gap for Gateway HTTP endpoints. When an endpoint is denied, <code>doctor --fix</code> can disable it precisely while keeping the rest of the endpoint configuration intact.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-policy-doctor-endpoint-repair.png\" alt=\"OpenClaw Doctor Can Repair Denied Gateway Endpoints\" /></p>",
      "date_published": "2026-07-07T23:30:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Doctor",
        "Repair",
        "Denied",
        "Gateway",
        "Endpoints"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-policy-doctor-endpoint-repair.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-policy-doctor-endpoint-repair.png",
          "mime_type": "image/png",
          "title": "OpenClaw Doctor Can Repair Denied Gateway Endpoints cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-state-dir-isolation/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-state-dir-isolation/",
      "title": "OpenClaw Tightens State Directory Isolation",
      "summary": "OpenClaw now skips app-group identity migration when OPENCLAW_STATE_DIR is set, protecting relocated stores and local tests.",
      "content_text": "OpenClaw merged [PR #101779, \"fix(shared): skip app-group identity migration when OPENCLAW_STATE_DIR is overridden\"](https://github.com/openclaw/openclaw/pull/101779), a P1 state-isolation fix for Mac app and shared OpenClawKit flows.\n\nThe immediate symptom was local test failure on Macs that had previously paired the OpenClaw app. The deeper issue was more important: a fresh overridden state directory could silently import real app-group device identity and auth tokens from the machine's normal OpenClaw store.\n\n## What Changed\n\nOpenClaw's shared device identity path logic now treats an explicit `OPENCLAW_STATE_DIR` override as a hard boundary. When that environment variable is set, app-group migration returns no source and does not import the machine's real paired identity into the override directory.\n\nDefault store selection remains unchanged. The fix applies to relocated or test stores that explicitly opt into a different state directory.\n\nThe PR also updates the test isolation trait so gated tests pin `OPENCLAW_STATE_DIR` to a fresh temp directory, then restore either the launch value or a run-scoped quarantine directory afterward. That prevents late writes from reconnect tasks from falling back into a developer's real store.\n\n## Why It Matters\n\nState directory overrides are used in tests, development, relocated installs, and isolated operator setups. Those directories are expected to be separate from the user's real app identity.\n\nIf a supposedly fresh directory imports a real `device.json` or `device-auth.json`, two bad things can happen:\n\n- Tests become non-deterministic because they see a developer's real pairing state.\n- Test literals or local experiments can overwrite or contaminate real device auth state.\n\nThe PR body says the old behavior could clobber a real node token with a test literal. That is exactly the kind of boundary bug that is easy to miss because clean CI machines pass while local, paired machines fail.\n\n## Operator Impact\n\nFor normal users, default app behavior should not change. OpenClaw still uses the normal container or legacy store path when no override is set.\n\nFor developers and operators using explicit state directories, the behavior is now more predictable. A relocated store should start as the relocated store, not as a copy of whatever identity happened to live in the app-group container.\n\n## Test Cleanup\n\nThe PR also removes repeated hand-written `setenv`/restore blocks from a dozen tests and moves that responsibility into `StateDirectoryIsolationTrait`. That is less exciting than the production fix, but it matters for keeping the boundary consistent.\n\nWhen isolation lives in one trait, future tests are less likely to forget the cleanup step or accidentally leave the process pointed at a real user store.\n\n## Validation\n\nThe PR reports a before/after reproduction on a Mac with real pairing state. Before the fix, two `GatewayNodeSessionTests` loaded the machine's real tokens. After the fix, the targeted OpenClawKit test set passed 44 of 44 tests on the same polluted Mac.\n\nIt also reports a broader package run with 600 tests across 55 suites green except one unrelated existing reconnect-timeout flake, plus byte checks confirming real machine stores kept only real tokens and no test literals.\n\n## Bottom Line\n\nOpenClaw now respects `OPENCLAW_STATE_DIR` as an isolation boundary. That is a quiet but important hardening step for local development, test reliability, and any setup that deliberately keeps state outside the default app store.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101779\">PR #101779, \"fix(shared): skip app-group identity migration when OPENCLAW_STATE_DIR is overridden\"</a>, a P1 state-isolation fix for Mac app and shared OpenClawKit flows.</p><p>The immediate symptom was local test failure on Macs that had previously paired the OpenClaw app. The deeper issue was more important: a fresh overridden state directory could silently import real app-group device identity and auth tokens from the machine's normal OpenClaw store.</p><h2>What Changed</h2><p>OpenClaw's shared device identity path logic now treats an explicit <code>OPENCLAW_STATE_DIR</code> override as a hard boundary. When that environment variable is set, app-group migration returns no source and does not import the machine's real paired identity into the override directory.</p><p>Default store selection remains unchanged. The fix applies to relocated or test stores that explicitly opt into a different state directory.</p><p>The PR also updates the test isolation trait so gated tests pin <code>OPENCLAW_STATE_DIR</code> to a fresh temp directory, then restore either the launch value or a run-scoped quarantine directory afterward. That prevents late writes from reconnect tasks from falling back into a developer's real store.</p><h2>Why It Matters</h2><p>State directory overrides are used in tests, development, relocated installs, and isolated operator setups. Those directories are expected to be separate from the user's real app identity.</p><p>If a supposedly fresh directory imports a real <code>device.json</code> or <code>device-auth.json</code>, two bad things can happen:</p><ul><li>Tests become non-deterministic because they see a developer's real pairing state.</li><li>Test literals or local experiments can overwrite or contaminate real device auth state.</li></ul><p>The PR body says the old behavior could clobber a real node token with a test literal. That is exactly the kind of boundary bug that is easy to miss because clean CI machines pass while local, paired machines fail.</p><h2>Operator Impact</h2><p>For normal users, default app behavior should not change. OpenClaw still uses the normal container or legacy store path when no override is set.</p><p>For developers and operators using explicit state directories, the behavior is now more predictable. A relocated store should start as the relocated store, not as a copy of whatever identity happened to live in the app-group container.</p><h2>Test Cleanup</h2><p>The PR also removes repeated hand-written <code>setenv</code>/restore blocks from a dozen tests and moves that responsibility into <code>StateDirectoryIsolationTrait</code>. That is less exciting than the production fix, but it matters for keeping the boundary consistent.</p><p>When isolation lives in one trait, future tests are less likely to forget the cleanup step or accidentally leave the process pointed at a real user store.</p><h2>Validation</h2><p>The PR reports a before/after reproduction on a Mac with real pairing state. Before the fix, two <code>GatewayNodeSessionTests</code> loaded the machine's real tokens. After the fix, the targeted OpenClawKit test set passed 44 of 44 tests on the same polluted Mac.</p><p>It also reports a broader package run with 600 tests across 55 suites green except one unrelated existing reconnect-timeout flake, plus byte checks confirming real machine stores kept only real tokens and no test literals.</p><h2>Bottom Line</h2><p>OpenClaw now respects <code>OPENCLAW_STATE_DIR</code> as an isolation boundary. That is a quiet but important hardening step for local development, test reliability, and any setup that deliberately keeps state outside the default app store.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-state-dir-isolation.png\" alt=\"OpenClaw Tightens State Directory Isolation\" /></p>",
      "date_published": "2026-07-07T23:20:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Guides",
        "Tightens",
        "State",
        "Directory",
        "Isolation"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-state-dir-isolation.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-state-dir-isolation.png",
          "mime_type": "image/png",
          "title": "OpenClaw Tightens State Directory Isolation cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-cron-event-triggers/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-cron-event-triggers/",
      "title": "OpenClaw Adds Cron Event Triggers",
      "summary": "OpenClaw cron jobs can now poll external conditions with headless scripts, waking agents only when watched state changes.",
      "content_text": "OpenClaw merged [PR #101195, \"feat(cron): event triggers — polled condition-watcher scripts via code mode\"](https://github.com/openclaw/openclaw/pull/101195), a major automation update for operators who want agents to react to outside state without waking a full model loop every few seconds.\n\nThe practical example from the PR is simple: \"wake me when CI on PR 123 changes status.\" Before this change, that kind of watcher usually meant a heartbeat or scheduled cron run would wake the agent, spend tokens, inspect the outside system, and then do nothing if nothing changed.\n\nNow cron can evaluate a small condition script first. The agent wakes only when the script reports that the watched state changed.\n\n## What Changed\n\nCron jobs on `every` and `cron` schedules can now carry an optional `trigger` object with a JavaScript condition script. OpenClaw evaluates that script headlessly in the existing code-mode QuickJS sandbox on each due tick.\n\nThe trigger script returns a small result:\n\n- `fire: true` runs the normal cron payload.\n- `message` can add context to the fired run.\n- `state` persists watcher state for the next tick.\n- `once` can disarm the trigger after the first successful fired payload.\n\nThat means a watcher can remember the last CI status, feed item, deployment phase, ticket state, or any other tool-readable marker, then wake the agent only when the marker changes.\n\n## Why It Matters\n\nThis is a good fit for OpenClaw's automation model because it separates cheap condition checks from expensive agent turns.\n\nPolling is not glamorous, but it is often the most reliable integration shape for real-world tools. Many services do not have webhooks. Some webhooks are hard to expose from a private gateway. Others are unreliable or require per-source glue code.\n\nWith this PR, anything an authorized tool can read can become a cron trigger source without adding core integration code.\n\n## Guardrails\n\nThe feature is off by default behind `cron.triggers.enabled`. That matters because the scripts run unattended with the owning agent's tool policy. If the agent can call powerful tools, the trigger script can too.\n\nOpenClaw adds several bounds around that execution:\n\n- 30-second wall-clock budget per evaluation.\n- 5 tool calls per evaluation.\n- 16KB persisted trigger state cap.\n- 30-second minimum poll interval by default.\n- Maximum 3 concurrent trigger evaluations.\n- Existing before-tool-call hooks still wrap script-initiated calls.\n\nThe PR also avoids creating sessions or snapshots for quiet trigger ticks. If the trigger does not fire, it should stay a cheap scheduler check rather than becoming another transcript.\n\n## Reliability Details\n\nOne subtle design choice is important: fired-run state persists only after the payload succeeds. If the payload wakes and then fails, the trigger can detect the same state again and retry instead of silently losing the event.\n\nForce-runs also bypass trigger evaluation, so operators can still manually run the job even when the condition is false.\n\n## Validation\n\nThe PR reports broad coverage across headless code-mode execution, trigger script parsing, state caps, concurrency handling, quiet ticks, fired run logs, force-run behavior, CLI flags, RPC gates, and configuration validation.\n\nIt also reports a green full `pnpm check:changed` run on Blacksmith Testbox and a clean structured Codex autoreview after earlier review rounds caught and fixed real bugs around trigger catch-up and cron staggering.\n\n## Bottom Line\n\nOpenClaw cron is moving from \"run on a clock\" toward \"watch state, then wake the agent.\" For operators running lots of automations, that should mean fewer wasted model turns and cleaner event-driven workflows.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101195\">PR #101195, \"feat(cron): event triggers — polled condition-watcher scripts via code mode\"</a>, a major automation update for operators who want agents to react to outside state without waking a full model loop every few seconds.</p><p>The practical example from the PR is simple: \"wake me when CI on PR 123 changes status.\" Before this change, that kind of watcher usually meant a heartbeat or scheduled cron run would wake the agent, spend tokens, inspect the outside system, and then do nothing if nothing changed.</p><p>Now cron can evaluate a small condition script first. The agent wakes only when the script reports that the watched state changed.</p><h2>What Changed</h2><p>Cron jobs on <code>every</code> and <code>cron</code> schedules can now carry an optional <code>trigger</code> object with a JavaScript condition script. OpenClaw evaluates that script headlessly in the existing code-mode QuickJS sandbox on each due tick.</p><p>The trigger script returns a small result:</p><ul><li><code>fire: true</code> runs the normal cron payload.</li><li><code>message</code> can add context to the fired run.</li><li><code>state</code> persists watcher state for the next tick.</li><li><code>once</code> can disarm the trigger after the first successful fired payload.</li></ul><p>That means a watcher can remember the last CI status, feed item, deployment phase, ticket state, or any other tool-readable marker, then wake the agent only when the marker changes.</p><h2>Why It Matters</h2><p>This is a good fit for OpenClaw's automation model because it separates cheap condition checks from expensive agent turns.</p><p>Polling is not glamorous, but it is often the most reliable integration shape for real-world tools. Many services do not have webhooks. Some webhooks are hard to expose from a private gateway. Others are unreliable or require per-source glue code.</p><p>With this PR, anything an authorized tool can read can become a cron trigger source without adding core integration code.</p><h2>Guardrails</h2><p>The feature is off by default behind <code>cron.triggers.enabled</code>. That matters because the scripts run unattended with the owning agent's tool policy. If the agent can call powerful tools, the trigger script can too.</p><p>OpenClaw adds several bounds around that execution:</p><ul><li>30-second wall-clock budget per evaluation.</li><li>5 tool calls per evaluation.</li><li>16KB persisted trigger state cap.</li><li>30-second minimum poll interval by default.</li><li>Maximum 3 concurrent trigger evaluations.</li><li>Existing before-tool-call hooks still wrap script-initiated calls.</li></ul><p>The PR also avoids creating sessions or snapshots for quiet trigger ticks. If the trigger does not fire, it should stay a cheap scheduler check rather than becoming another transcript.</p><h2>Reliability Details</h2><p>One subtle design choice is important: fired-run state persists only after the payload succeeds. If the payload wakes and then fails, the trigger can detect the same state again and retry instead of silently losing the event.</p><p>Force-runs also bypass trigger evaluation, so operators can still manually run the job even when the condition is false.</p><h2>Validation</h2><p>The PR reports broad coverage across headless code-mode execution, trigger script parsing, state caps, concurrency handling, quiet ticks, fired run logs, force-run behavior, CLI flags, RPC gates, and configuration validation.</p><p>It also reports a green full <code>pnpm check:changed</code> run on Blacksmith Testbox and a clean structured Codex autoreview after earlier review rounds caught and fixed real bugs around trigger catch-up and cron staggering.</p><h2>Bottom Line</h2><p>OpenClaw cron is moving from \"run on a clock\" toward \"watch state, then wake the agent.\" For operators running lots of automations, that should mean fewer wasted model turns and cleaner event-driven workflows.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-cron-event-triggers.png\" alt=\"OpenClaw Adds Cron Event Triggers\" /></p>",
      "date_published": "2026-07-07T23:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Adds",
        "Cron",
        "Event",
        "Triggers"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-cron-event-triggers.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-cron-event-triggers.png",
          "mime_type": "image/png",
          "title": "OpenClaw Adds Cron Event Triggers cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-clawhub-promos-cli/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-clawhub-promos-cli/",
      "title": "OpenClaw Adds ClawHub Promo Claims",
      "summary": "OpenClaw now includes a promos CLI for discovering and claiming time-boxed ClawHub model offers without rerunning onboarding.",
      "content_text": "OpenClaw merged [PR #100236, \"feat(cli): add openclaw promos to discover and claim ClawHub promotional model offers\"](https://github.com/openclaw/openclaw/pull/100236), adding a new CLI path for time-boxed ClawHub model promotions.\n\nThe feature gives existing users a way to see and claim promotional model offers without rerunning onboarding or hand-editing config. It also introduces passive discovery so live offers can appear where users already inspect models.\n\n## What Changed\n\nOpenClaw now has an `openclaw promos` command group with:\n\n- `openclaw promos list`\n- `openclaw promos claim <slug>`\n\nThe claim flow can reuse existing provider credentials when the relevant provider plugin is installed, or run the provider's normal auth-choice flow when it is not. Non-interactive use is supported through the same API-key style contract used by onboarding, and setting the suggested model as default remains explicit rather than automatic.\n\nClaimed models are registered through OpenClaw's canonical model config mutators. Aliases follow the existing model-alias contract and do not overwrite existing aliases.\n\n## Passive Discovery\n\nThe PR also adds a promotions feed used by `models list`. OpenClaw can fetch ClawHub's hosted promotions snapshot on a 24-hour cadence, cache it in the existing shared SQLite state database, and render live unconfigured offers under an \"Available via promotion\" group.\n\nThat network path is designed to fail silently. It is conditional, cache-backed, and separate from update checks, so promotions discovery should not delay or break normal model listing.\n\nFor machine output, the feature stays quiet: `--json` and `--plain` do not include the human-facing promotion notice.\n\n## Safety Model\n\nThe PR treats remote promotion payloads as declarative data, not instructions. The body says slugs, model refs, providers, auth choice IDs, and plugin names are contract-validated at the parse boundary. Display text is terminal-sanitized before output.\n\nThat matters because a promotions feed is remote and time-sensitive. A malformed or compromised promotion should not be able to execute commands, print terminal controls, or generate unsafe copy-paste instructions.\n\nThe claim path also revalidates against the live API, so ClawHub can kill an offer even if a cached feed still mentions it.\n\n## Validation\n\nThe PR reports 46 new unit tests across claim, list, feed validation, cache behavior, promotion rendering, and claim provenance. It also reports passing core typechecks, lint, formatting, docs link checks, docs map checks, and a full build.\n\nThe author also ran a live end-to-end test against a local ClawHub instance in an isolated state directory: the first `models list` fetched and rendered a live offer, the second used the cadence gate and suppressed the one-time notice, and JSON output stayed clean.\n\n## Bottom Line\n\nOpenClaw is turning ClawHub promotions into a first-class CLI workflow. Users can discover, inspect, and claim offers quickly, while OpenClaw keeps remote promotion data fenced behind validation and explicit user consent.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100236\">PR #100236, \"feat(cli): add openclaw promos to discover and claim ClawHub promotional model offers\"</a>, adding a new CLI path for time-boxed ClawHub model promotions.</p><p>The feature gives existing users a way to see and claim promotional model offers without rerunning onboarding or hand-editing config. It also introduces passive discovery so live offers can appear where users already inspect models.</p><h2>What Changed</h2><p>OpenClaw now has an <code>openclaw promos</code> command group with:</p><ul><li><code>openclaw promos list</code></li><li><code>openclaw promos claim <slug></code></li></ul><p>The claim flow can reuse existing provider credentials when the relevant provider plugin is installed, or run the provider's normal auth-choice flow when it is not. Non-interactive use is supported through the same API-key style contract used by onboarding, and setting the suggested model as default remains explicit rather than automatic.</p><p>Claimed models are registered through OpenClaw's canonical model config mutators. Aliases follow the existing model-alias contract and do not overwrite existing aliases.</p><h2>Passive Discovery</h2><p>The PR also adds a promotions feed used by <code>models list</code>. OpenClaw can fetch ClawHub's hosted promotions snapshot on a 24-hour cadence, cache it in the existing shared SQLite state database, and render live unconfigured offers under an \"Available via promotion\" group.</p><p>That network path is designed to fail silently. It is conditional, cache-backed, and separate from update checks, so promotions discovery should not delay or break normal model listing.</p><p>For machine output, the feature stays quiet: <code>--json</code> and <code>--plain</code> do not include the human-facing promotion notice.</p><h2>Safety Model</h2><p>The PR treats remote promotion payloads as declarative data, not instructions. The body says slugs, model refs, providers, auth choice IDs, and plugin names are contract-validated at the parse boundary. Display text is terminal-sanitized before output.</p><p>That matters because a promotions feed is remote and time-sensitive. A malformed or compromised promotion should not be able to execute commands, print terminal controls, or generate unsafe copy-paste instructions.</p><p>The claim path also revalidates against the live API, so ClawHub can kill an offer even if a cached feed still mentions it.</p><h2>Validation</h2><p>The PR reports 46 new unit tests across claim, list, feed validation, cache behavior, promotion rendering, and claim provenance. It also reports passing core typechecks, lint, formatting, docs link checks, docs map checks, and a full build.</p><p>The author also ran a live end-to-end test against a local ClawHub instance in an isolated state directory: the first <code>models list</code> fetched and rendered a live offer, the second used the cadence gate and suppressed the one-time notice, and JSON output stayed clean.</p><h2>Bottom Line</h2><p>OpenClaw is turning ClawHub promotions into a first-class CLI workflow. Users can discover, inspect, and claim offers quickly, while OpenClaw keeps remote promotion data fenced behind validation and explicit user consent.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-clawhub-promos-cli.png\" alt=\"OpenClaw Adds ClawHub Promo Claims\" /></p>",
      "date_published": "2026-07-07T08:30:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Adds",
        "Clawhub",
        "Promo",
        "Claims"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-clawhub-promos-cli.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-clawhub-promos-cli.png",
          "mime_type": "image/png",
          "title": "OpenClaw Adds ClawHub Promo Claims cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-webchat-owner-tools/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-webchat-owner-tools/",
      "title": "OpenClaw Restores WebChat Owner Tools",
      "summary": "OpenClaw now keeps owner tools available in WebChat while preserving restrictive sender policies for external channels.",
      "content_text": "OpenClaw merged [PR #101271, \"fix: keep owner tools available in WebChat\"](https://github.com/openclaw/openclaw/pull/101271), a capability-boundary fix for authenticated owners using Control UI and WebChat.\n\nThe issue affected installations with a restrictive default sender policy. Those policies are meant to limit what unidentified or external senders can do. In this case, they could also reduce an authenticated owner inside WebChat to a much smaller web/media tool set.\n\n## What Changed\n\nTrusted owner turns on the internal WebChat channel now bypass the wildcard sender policy intended for unidentified senders. External channels still apply that wildcard policy, and plugin harness selection now uses the same owner-aware capability decision.\n\nThe important distinction is not \"more tools everywhere.\" It is \"owner tools for owner WebChat turns.\"\n\nThe PR keeps the boundary narrow:\n\n- Authenticated owner in WebChat keeps configured shell, filesystem, and other owner tools.\n- Unidentified senders remain governed by the wildcard sender policy.\n- Owner turns through external channels such as Discord stay restricted when policy says they should.\n- Harness selection follows the same owner-aware rule instead of drifting into a different capability profile.\n\n## Why It Matters\n\nControl UI is where many operators expect the full owner experience. If WebChat silently falls back to an external-sender profile, the UI can look broken: commands disappear, filesystem work is unavailable, and ordinary owner workflows fail even though the operator is authenticated.\n\nAt the same time, relaxing sender policy too broadly would be dangerous. OpenClaw installations often expose channel plugins to people, groups, or automations that should not receive owner-grade tools.\n\nThis PR fixes the owner experience without turning the wildcard sender policy into a global bypass.\n\n## Proof From The PR\n\nThe PR body reports live authenticated Control UI/WebChat verification where the fixed session compiled 28 tools, including `exec`, `read`, `write`, and `process`, then successfully executed a shell command. Before the fix, the same WebChat session compiled only 6 restricted tools.\n\nRegression coverage also checks that owner WebChat bypasses the wildcard sender policy while owner turns on Discord remain restricted.\n\n## Validation\n\nThe reported test evidence includes 68 focused tests across conversation capability profile and harness selection, a passing core typecheck, a full build, and a branch-mode autoreview with no actionable findings.\n\n## Bottom Line\n\nOpenClaw now preserves the tool boundary operators expect: WebChat owners keep owner tools, while external and unidentified senders remain constrained by sender policy.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101271\">PR #101271, \"fix: keep owner tools available in WebChat\"</a>, a capability-boundary fix for authenticated owners using Control UI and WebChat.</p><p>The issue affected installations with a restrictive default sender policy. Those policies are meant to limit what unidentified or external senders can do. In this case, they could also reduce an authenticated owner inside WebChat to a much smaller web/media tool set.</p><h2>What Changed</h2><p>Trusted owner turns on the internal WebChat channel now bypass the wildcard sender policy intended for unidentified senders. External channels still apply that wildcard policy, and plugin harness selection now uses the same owner-aware capability decision.</p><p>The important distinction is not \"more tools everywhere.\" It is \"owner tools for owner WebChat turns.\"</p><p>The PR keeps the boundary narrow:</p><ul><li>Authenticated owner in WebChat keeps configured shell, filesystem, and other owner tools.</li><li>Unidentified senders remain governed by the wildcard sender policy.</li><li>Owner turns through external channels such as Discord stay restricted when policy says they should.</li><li>Harness selection follows the same owner-aware rule instead of drifting into a different capability profile.</li></ul><h2>Why It Matters</h2><p>Control UI is where many operators expect the full owner experience. If WebChat silently falls back to an external-sender profile, the UI can look broken: commands disappear, filesystem work is unavailable, and ordinary owner workflows fail even though the operator is authenticated.</p><p>At the same time, relaxing sender policy too broadly would be dangerous. OpenClaw installations often expose channel plugins to people, groups, or automations that should not receive owner-grade tools.</p><p>This PR fixes the owner experience without turning the wildcard sender policy into a global bypass.</p><h2>Proof From The PR</h2><p>The PR body reports live authenticated Control UI/WebChat verification where the fixed session compiled 28 tools, including <code>exec</code>, <code>read</code>, <code>write</code>, and <code>process</code>, then successfully executed a shell command. Before the fix, the same WebChat session compiled only 6 restricted tools.</p><p>Regression coverage also checks that owner WebChat bypasses the wildcard sender policy while owner turns on Discord remain restricted.</p><h2>Validation</h2><p>The reported test evidence includes 68 focused tests across conversation capability profile and harness selection, a passing core typecheck, a full build, and a branch-mode autoreview with no actionable findings.</p><h2>Bottom Line</h2><p>OpenClaw now preserves the tool boundary operators expect: WebChat owners keep owner tools, while external and unidentified senders remain constrained by sender policy.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-webchat-owner-tools.png\" alt=\"OpenClaw Restores WebChat Owner Tools\" /></p>",
      "date_published": "2026-07-07T08:20:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Restores",
        "Webchat",
        "Owner",
        "Tools"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-webchat-owner-tools.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-webchat-owner-tools.png",
          "mime_type": "image/png",
          "title": "OpenClaw Restores WebChat Owner Tools cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-7-gateway-login-isolation/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-7-gateway-login-isolation/",
      "title": "OpenClaw Keeps Gateway Logins Separate",
      "summary": "OpenClaw now scopes Control UI device credentials per gateway endpoint, preventing same-origin routes from overwriting each other.",
      "content_text": "OpenClaw merged [PR #101352, \"fix(ui): preserve login across same-origin gateways\"](https://github.com/openclaw/openclaw/pull/101352), a P1 Control UI authentication fix for operators who run multiple gateways behind the same HTTPS origin.\n\nThe bug showed up when different gateways lived under different paths or query routes on one host. A browser tab for one gateway could reuse another gateway's cached device token, fail the handshake, and show the login gate again even though the shared gateway token itself had not changed.\n\n## What Changed\n\nThe browser now stores gateway-issued device credentials under the exact normalized endpoint. That scope includes protocol, host, path, and query, while excluding the fragment.\n\nThat means two gateways on the same origin can keep separate device-bound credentials:\n\n- `https://example.com/rosita`\n- `https://example.com/wilfred`\n- `https://example.com/control?gateway=rosita`\n\nDevice identity can still be shared, but each gateway now reuses only the token that gateway issued. During upgrade, OpenClaw claims the old origin-wide record for the first gateway that opens, migrates it to the exact endpoint scope, then deletes the legacy record so sibling routes cannot consume it.\n\n## Why It Matters\n\nMulti-gateway layouts are common for people running separate OpenClaw agents, environments, or access boundaries behind one domain. A login cache that is too broad can make those deployments feel flaky: one route works, another route reloads, and suddenly a user sees an auth prompt that looks like a token rotation or gateway outage.\n\nThe PR narrows that failure mode. Reloading one Control UI route should no longer overwrite a sibling route's cached device credential. Updates and restarts should also be less likely to masquerade as auth churn when the actual issue is a mismatched device token.\n\n## Security Boundary\n\nThe PR explicitly keeps the master gateway token out of persistent browser storage and avoids broadcasting it between tabs. Fresh tabs still rely on revocable, gateway-issued, device-bound credentials.\n\nThat is the right shape for this class of fix: make the cache more precise without turning a convenience credential into a broader bearer secret.\n\n## Validation\n\nThe PR reports regression coverage for same-origin path routes, query routes, legacy record migration, and cleanup-failure handling. It also reports a Chromium end-to-end test proving an independently opened tab reconnects with the gateway-issued device token rather than showing the login gate.\n\nThe author also lists a full Control UI suite run: 141 files and 2,287 tests passed, plus focused auth/settings coverage, type-aware lint, Chromium E2E, and production builds.\n\n## Bottom Line\n\nOpenClaw's Control UI now treats each gateway endpoint as its own credential scope. Operators can keep multiple gateways under one origin without one login silently poisoning another.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101352\">PR #101352, \"fix(ui): preserve login across same-origin gateways\"</a>, a P1 Control UI authentication fix for operators who run multiple gateways behind the same HTTPS origin.</p><p>The bug showed up when different gateways lived under different paths or query routes on one host. A browser tab for one gateway could reuse another gateway's cached device token, fail the handshake, and show the login gate again even though the shared gateway token itself had not changed.</p><h2>What Changed</h2><p>The browser now stores gateway-issued device credentials under the exact normalized endpoint. That scope includes protocol, host, path, and query, while excluding the fragment.</p><p>That means two gateways on the same origin can keep separate device-bound credentials:</p><ul><li><code>https://example.com/rosita</code></li><li><code>https://example.com/wilfred</code></li><li><code>https://example.com/control?gateway=rosita</code></li></ul><p>Device identity can still be shared, but each gateway now reuses only the token that gateway issued. During upgrade, OpenClaw claims the old origin-wide record for the first gateway that opens, migrates it to the exact endpoint scope, then deletes the legacy record so sibling routes cannot consume it.</p><h2>Why It Matters</h2><p>Multi-gateway layouts are common for people running separate OpenClaw agents, environments, or access boundaries behind one domain. A login cache that is too broad can make those deployments feel flaky: one route works, another route reloads, and suddenly a user sees an auth prompt that looks like a token rotation or gateway outage.</p><p>The PR narrows that failure mode. Reloading one Control UI route should no longer overwrite a sibling route's cached device credential. Updates and restarts should also be less likely to masquerade as auth churn when the actual issue is a mismatched device token.</p><h2>Security Boundary</h2><p>The PR explicitly keeps the master gateway token out of persistent browser storage and avoids broadcasting it between tabs. Fresh tabs still rely on revocable, gateway-issued, device-bound credentials.</p><p>That is the right shape for this class of fix: make the cache more precise without turning a convenience credential into a broader bearer secret.</p><h2>Validation</h2><p>The PR reports regression coverage for same-origin path routes, query routes, legacy record migration, and cleanup-failure handling. It also reports a Chromium end-to-end test proving an independently opened tab reconnects with the gateway-issued device token rather than showing the login gate.</p><p>The author also lists a full Control UI suite run: 141 files and 2,287 tests passed, plus focused auth/settings coverage, type-aware lint, Chromium E2E, and production builds.</p><h2>Bottom Line</h2><p>OpenClaw's Control UI now treats each gateway endpoint as its own credential scope. Operators can keep multiple gateways under one origin without one login silently poisoning another.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-gateway-login-isolation.png\" alt=\"OpenClaw Keeps Gateway Logins Separate\" /></p>",
      "date_published": "2026-07-07T08:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Keeps",
        "Gateway",
        "Logins",
        "Separate"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-gateway-login-isolation.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-7-gateway-login-isolation.png",
          "mime_type": "image/png",
          "title": "OpenClaw Keeps Gateway Logins Separate cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-browser-cdp-host-policy/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-browser-cdp-host-policy/",
      "title": "OpenClaw Locks Browser CDP to Its Host",
      "summary": "OpenClaw now isolates CDP control host policy so browser discovery cannot pivot control traffic to another allowed navigation host.",
      "content_text": "OpenClaw merged [PR #101171, \"fix(browser): keep CDP discovery on the configured host\"](https://github.com/openclaw/openclaw/pull/101171), a browser automation hardening fix around Chrome DevTools Protocol discovery and host policy.\n\nThe affected path is specific, but the boundary is important. Users can configure browser navigation policies that allow certain hosts. CDP control is different from page navigation: it is the control channel for browser automation itself. The PR fixes a case where discovery could follow a returned debugger WebSocket to a host other than the configured browser endpoint under permissive or multi-host policies.\n\n## What Changed\n\nCDP control now receives a dedicated exact-host policy. OpenClaw still preserves the existing remote `hostnameAllowlist` gate, and configured local relays keep their loopback control exception.\n\nThe key distinction is that discovered endpoints cannot claim a loopback exception just because a page-navigation policy allows broader hosts. Persistent Playwright tab creation and permission routes also use the control policy only for CDP connections while retaining the page policy for actual navigation.\n\nThat keeps two concerns separate: where pages may go, and where OpenClaw may send browser-control traffic.\n\n## Why It Matters\n\nBrowser automation is powerful because it can read pages, control tabs, grant permissions, and drive workflows that look like a human using a browser. That also means the CDP endpoint deserves a tighter trust model than ordinary web navigation.\n\nIf a permissive navigation policy can influence CDP discovery, a malicious or misconfigured endpoint may be able to move control traffic or CDP URL credentials somewhere the operator did not intend. The PR closes that gap by binding browser control back to the configured host.\n\nThis is not meant to block legitimate managed-browser setups. The PR body notes that managed and extension loopback profiles still work under strict navigation rules, and explicitly allowed remote CDP profiles remain supported.\n\n## Validation\n\nThe PR reports regressions for strict, permissive, wildcard, trailing-dot, extension-loopback, discovered-endpoint, persistent Playwright, and permission-route cases. It also includes a live run with real Chrome 150, Gateway, and an `openai/gpt-5.4` agent: CDP open/list worked under a restrictive navigation allowlist, while direct and agent navigation to `openai.com` were policy-blocked.\n\n## Bottom Line\n\nOpenClaw now treats CDP discovery as browser-control traffic, not ordinary browsing. That keeps navigation flexibility while making the control plane stick to the configured browser endpoint.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/101171\">PR #101171, \"fix(browser): keep CDP discovery on the configured host\"</a>, a browser automation hardening fix around Chrome DevTools Protocol discovery and host policy.</p><p>The affected path is specific, but the boundary is important. Users can configure browser navigation policies that allow certain hosts. CDP control is different from page navigation: it is the control channel for browser automation itself. The PR fixes a case where discovery could follow a returned debugger WebSocket to a host other than the configured browser endpoint under permissive or multi-host policies.</p><h2>What Changed</h2><p>CDP control now receives a dedicated exact-host policy. OpenClaw still preserves the existing remote <code>hostnameAllowlist</code> gate, and configured local relays keep their loopback control exception.</p><p>The key distinction is that discovered endpoints cannot claim a loopback exception just because a page-navigation policy allows broader hosts. Persistent Playwright tab creation and permission routes also use the control policy only for CDP connections while retaining the page policy for actual navigation.</p><p>That keeps two concerns separate: where pages may go, and where OpenClaw may send browser-control traffic.</p><h2>Why It Matters</h2><p>Browser automation is powerful because it can read pages, control tabs, grant permissions, and drive workflows that look like a human using a browser. That also means the CDP endpoint deserves a tighter trust model than ordinary web navigation.</p><p>If a permissive navigation policy can influence CDP discovery, a malicious or misconfigured endpoint may be able to move control traffic or CDP URL credentials somewhere the operator did not intend. The PR closes that gap by binding browser control back to the configured host.</p><p>This is not meant to block legitimate managed-browser setups. The PR body notes that managed and extension loopback profiles still work under strict navigation rules, and explicitly allowed remote CDP profiles remain supported.</p><h2>Validation</h2><p>The PR reports regressions for strict, permissive, wildcard, trailing-dot, extension-loopback, discovered-endpoint, persistent Playwright, and permission-route cases. It also includes a live run with real Chrome 150, Gateway, and an <code>openai/gpt-5.4</code> agent: CDP open/list worked under a restrictive navigation allowlist, while direct and agent navigation to <code>openai.com</code> were policy-blocked.</p><h2>Bottom Line</h2><p>OpenClaw now treats CDP discovery as browser-control traffic, not ordinary browsing. That keeps navigation flexibility while making the control plane stick to the configured browser endpoint.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-browser-cdp-host-policy.png\" alt=\"OpenClaw Locks Browser CDP to Its Host\" /></p>",
      "date_published": "2026-07-06T23:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Locks",
        "Browser",
        "Host"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-browser-cdp-host-policy.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-browser-cdp-host-policy.png",
          "mime_type": "image/png",
          "title": "OpenClaw Locks Browser CDP to Its Host cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-realtime-voice-barge-in/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-realtime-voice-barge-in/",
      "title": "OpenClaw Fixes Realtime Voice Barge-In",
      "summary": "OpenClaw now has a provider-neutral voice interruption contract so callers can stop assistant audio cleanly during realtime calls.",
      "content_text": "OpenClaw merged [PR #90749, \"Fix realtime voice-call barge-in cancellation\"](https://github.com/openclaw/openclaw/pull/90749), a P1 voice-call fix that makes assistant audio interruption behave consistently across realtime providers.\n\nThe problem was subtle but user-visible. During realtime voice calls, a caller could start speaking while assistant audio was still playing, yet the assistant's previous audio could continue. OpenClaw had local MuLaw interruption detection, provider-side speech detection, Twilio playback buffers, and Talk-turn cancellation all touching the same moment from different angles.\n\nThe fix gives those pieces one clearer contract.\n\n## What Changed\n\nRealtime providers can now report an accepted interruption through `onClearAudio(\"barge-in\")`. The voice-call audio sink owns the transport response: clear the Twilio pacer and cancel the canonical Talk turn once.\n\nOpenAI and Google map into that contract differently. OpenAI emits the signal after its configured speech-start policy accepts server VAD. Google emits it for `serverContent.interrupted`. Providers that do not advertise input-audio barge-in support keep the local MuLaw fallback path.\n\nThe important part is that OpenClaw no longer treats barge-in as an OpenAI-only websocket special case. It becomes a provider-neutral voice runtime behavior.\n\n## Why It Matters\n\nBarge-in is one of the details that decides whether voice feels natural or broken. If a human interrupts an assistant, the assistant needs to stop quickly and predictably. Continuing to play stale audio after the caller has started talking makes the call feel laggy, and it can cause the next turn to start from the wrong conversational state.\n\nFor OpenClaw, this matters beyond voice polish. Realtime voice calls sit at the edge of multiple systems: provider streaming, local audio detection, phone transport, and agent turn state. A clean interruption boundary reduces the chance that one layer clears audio while another layer keeps the old Talk turn alive.\n\n## Validation\n\nThe PR labels this as a compatibility and message-delivery risk, and reports sufficient proof across OpenAI and Google realtime behavior. The implementation keeps the gateway protocol and model catalog surface unchanged.\n\nThat is a practical choice. Users should see cleaner interruption behavior without needing new configuration or a provider-specific setup change.\n\n## Bottom Line\n\nOpenClaw's realtime voice barge-in path now has a single provider-neutral contract. When a caller interrupts, the system can clear playback and cancel the active Talk turn in one place instead of relying on provider-specific audio events leaking through the transport layer.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/90749\">PR #90749, \"Fix realtime voice-call barge-in cancellation\"</a>, a P1 voice-call fix that makes assistant audio interruption behave consistently across realtime providers.</p><p>The problem was subtle but user-visible. During realtime voice calls, a caller could start speaking while assistant audio was still playing, yet the assistant's previous audio could continue. OpenClaw had local MuLaw interruption detection, provider-side speech detection, Twilio playback buffers, and Talk-turn cancellation all touching the same moment from different angles.</p><p>The fix gives those pieces one clearer contract.</p><h2>What Changed</h2><p>Realtime providers can now report an accepted interruption through <code>onClearAudio(\"barge-in\")</code>. The voice-call audio sink owns the transport response: clear the Twilio pacer and cancel the canonical Talk turn once.</p><p>OpenAI and Google map into that contract differently. OpenAI emits the signal after its configured speech-start policy accepts server VAD. Google emits it for <code>serverContent.interrupted</code>. Providers that do not advertise input-audio barge-in support keep the local MuLaw fallback path.</p><p>The important part is that OpenClaw no longer treats barge-in as an OpenAI-only websocket special case. It becomes a provider-neutral voice runtime behavior.</p><h2>Why It Matters</h2><p>Barge-in is one of the details that decides whether voice feels natural or broken. If a human interrupts an assistant, the assistant needs to stop quickly and predictably. Continuing to play stale audio after the caller has started talking makes the call feel laggy, and it can cause the next turn to start from the wrong conversational state.</p><p>For OpenClaw, this matters beyond voice polish. Realtime voice calls sit at the edge of multiple systems: provider streaming, local audio detection, phone transport, and agent turn state. A clean interruption boundary reduces the chance that one layer clears audio while another layer keeps the old Talk turn alive.</p><h2>Validation</h2><p>The PR labels this as a compatibility and message-delivery risk, and reports sufficient proof across OpenAI and Google realtime behavior. The implementation keeps the gateway protocol and model catalog surface unchanged.</p><p>That is a practical choice. Users should see cleaner interruption behavior without needing new configuration or a provider-specific setup change.</p><h2>Bottom Line</h2><p>OpenClaw's realtime voice barge-in path now has a single provider-neutral contract. When a caller interrupts, the system can clear playback and cancel the active Talk turn in one place instead of relying on provider-specific audio events leaking through the transport layer.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-realtime-voice-barge-in.png\" alt=\"OpenClaw Fixes Realtime Voice Barge-In\" /></p>",
      "date_published": "2026-07-06T23:07:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Fixes",
        "Realtime",
        "Voice",
        "Barge"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-realtime-voice-barge-in.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-realtime-voice-barge-in.png",
          "mime_type": "image/png",
          "title": "OpenClaw Fixes Realtime Voice Barge-In cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-discord-attachment-preflight/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-discord-attachment-preflight/",
      "title": "OpenClaw Saves Discord Attachments Earlier",
      "summary": "OpenClaw now downloads Discord attachments at receipt time, keeping queued media available even when earlier agent runs delay processing.",
      "content_text": "OpenClaw merged [PR #96183, \"fix(discord): download attachments at receipt time, not after the run queue\"](https://github.com/openclaw/openclaw/pull/96183), a P1 Discord reliability fix for one of the most frustrating failure modes in busy agent channels: media that expires before the agent ever gets to process it.\n\nThe issue comes from Discord's signed attachment CDN URLs. Those URLs carry a fixed expiration time. If a message with an image, file, video, or forwarded attachment lands while OpenClaw is still working through an earlier request, the inbound run queue can delay processing long enough that the CDN URL is no longer usable.\n\nThe new behavior moves volatile media download work to the receipt boundary, before the queued agent job waits its turn.\n\n## What Changed\n\nThe Discord extension now resolves direct and forwarded attachments during authorized preflight. It combines the downloaded media into a required `preparedMedia` array and serializes that immutable snapshot into the queued inbound job.\n\nThat means the job no longer depends on a later fetch against a short-lived CDN URL. By the time the agent run starts, the media has already been captured under OpenClaw's own queued job payload.\n\nThe change also keeps bot-loop suppression before CDN I/O. If a Discord message is rejected as repeated bot traffic, OpenClaw does not download media and does not put that message into the run queue.\n\n## Why It Matters\n\nDiscord is often used as a shared command surface for OpenClaw. In that setup, attachments are not decoration. Screenshots, PDFs, logs, short videos, and forwarded files can be the entire task.\n\nWhen media expires between receipt and processing, the agent sees a weaker version of the user's request, or no useful artifact at all. That is especially painful in group channels where multiple requests may queue behind a long-running job.\n\nBy downloading media immediately, OpenClaw treats Discord attachment URLs as transport-time material rather than durable storage. That is the right boundary for signed URLs: capture them while valid, then hand stable media references to the run queue.\n\n## Validation\n\nThe PR reports a targeted Discord regression suite covering inbound delivery, forwarded attachments, bot-loop suppression, prepared media serialization, and queue processing.\n\nThe user-facing contract is narrow. Text-only messages keep their existing behavior. Attachment authorization checks remain in place. The main change is that media attached to a valid message survives queue delay instead of depending on Discord's CDN URL still being valid later.\n\n## Bottom Line\n\nOpenClaw now snapshots Discord attachments before an agent run waits in line. For operators who use Discord as a media-heavy command channel, this should make queued image, file, video, and forwarded-message tasks much more reliable.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/96183\">PR #96183, \"fix(discord): download attachments at receipt time, not after the run queue\"</a>, a P1 Discord reliability fix for one of the most frustrating failure modes in busy agent channels: media that expires before the agent ever gets to process it.</p><p>The issue comes from Discord's signed attachment CDN URLs. Those URLs carry a fixed expiration time. If a message with an image, file, video, or forwarded attachment lands while OpenClaw is still working through an earlier request, the inbound run queue can delay processing long enough that the CDN URL is no longer usable.</p><p>The new behavior moves volatile media download work to the receipt boundary, before the queued agent job waits its turn.</p><h2>What Changed</h2><p>The Discord extension now resolves direct and forwarded attachments during authorized preflight. It combines the downloaded media into a required <code>preparedMedia</code> array and serializes that immutable snapshot into the queued inbound job.</p><p>That means the job no longer depends on a later fetch against a short-lived CDN URL. By the time the agent run starts, the media has already been captured under OpenClaw's own queued job payload.</p><p>The change also keeps bot-loop suppression before CDN I/O. If a Discord message is rejected as repeated bot traffic, OpenClaw does not download media and does not put that message into the run queue.</p><h2>Why It Matters</h2><p>Discord is often used as a shared command surface for OpenClaw. In that setup, attachments are not decoration. Screenshots, PDFs, logs, short videos, and forwarded files can be the entire task.</p><p>When media expires between receipt and processing, the agent sees a weaker version of the user's request, or no useful artifact at all. That is especially painful in group channels where multiple requests may queue behind a long-running job.</p><p>By downloading media immediately, OpenClaw treats Discord attachment URLs as transport-time material rather than durable storage. That is the right boundary for signed URLs: capture them while valid, then hand stable media references to the run queue.</p><h2>Validation</h2><p>The PR reports a targeted Discord regression suite covering inbound delivery, forwarded attachments, bot-loop suppression, prepared media serialization, and queue processing.</p><p>The user-facing contract is narrow. Text-only messages keep their existing behavior. Attachment authorization checks remain in place. The main change is that media attached to a valid message survives queue delay instead of depending on Discord's CDN URL still being valid later.</p><h2>Bottom Line</h2><p>OpenClaw now snapshots Discord attachments before an agent run waits in line. For operators who use Discord as a media-heavy command channel, this should make queued image, file, video, and forwarded-message tasks much more reliable.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-discord-attachment-preflight.png\" alt=\"OpenClaw Saves Discord Attachments Earlier\" /></p>",
      "date_published": "2026-07-06T23:04:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Saves",
        "Discord",
        "Attachments",
        "Earlier"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-discord-attachment-preflight.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-discord-attachment-preflight.png",
          "mime_type": "image/png",
          "title": "OpenClaw Saves Discord Attachments Earlier cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-provider-response-bounds/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-provider-response-bounds/",
      "title": "OpenClaw Bounds OAuth and Webhook Responses",
      "summary": "OpenClaw now caps successful OpenRouter OAuth and Discord webhook JSON responses to avoid unbounded provider reads.",
      "content_text": "OpenClaw merged [PR #98098, \"fix(providers): bound successful OAuth and webhook responses\"](https://github.com/openclaw/openclaw/pull/98098), closing two remaining unbounded JSON response paths in provider-controlled flows.\n\nThe merged change covers successful Discord webhook execution responses and OpenRouter OAuth code exchange responses. Both now use OpenClaw's shared provider JSON response reader so oversized streams can be rejected and canceled instead of buffered without a bound.\n\nThis is a P2 fix, but it carries auth-provider and message-delivery risk labels. That combination is worth watching because the affected paths sit directly on provider and channel boundaries.\n\n## What Changed\n\nThe PR moves the remaining successful JSON reads to `readProviderJsonResponse`, the shared helper used to apply a response cap. The author notes that the original Google path was removed from scope because `fetchWithTimeout` already applies the same 16 MiB response cap, and the proposed Nextcloud path had already been fixed on `main`.\n\nThe Discord side keeps its existing transport contract. Discord webhook sends using `wait=false` can return `204` with no body, and optional response bodies after successful non-idempotent posts can be absent, malformed, or oversized without turning the already-completed send into an error that might trigger a duplicate bot fallback.\n\nThe OpenRouter OAuth side now rejects and cancels oversized successful responses during code exchange. That prevents a hostile or broken endpoint from forcing OpenClaw to buffer an unbounded body on a credential-adjacent path.\n\n## Why It Matters\n\nOpenClaw has been steadily tightening provider and channel response handling. Error responses are not the only risk. A successful response can still be oversized, malformed, or controlled by infrastructure outside the user's machine.\n\nThat matters for OAuth because credential flows should have predictable memory and parsing behavior. It also matters for Discord because message delivery paths must avoid both silent resource hazards and accidental duplicate sends.\n\nThe subtle part of this PR is that it hardens reads without changing the success semantics for Discord. OpenClaw can cancel an oversized optional body while still treating the non-idempotent webhook send as complete, avoiding a fallback message that could make users see two bot replies.\n\n## Validation\n\nThe PR reports a focused Blacksmith Testbox run covering formatting plus 12 Discord webhook tests and 9 OpenRouter OAuth tests. A changed gate also passed extension typechecks, test typechecks, lint, dependency guards, database-first guard, sidecar checks, and import-cycle checks.\n\nThe oversized-stream tests verify rejection and cancellation for OpenRouter, plus cancellation without duplicate-send failure for Discord. The author also ran unauthenticated live probes against current Discord, OpenRouter, and Google JSON error endpoints without using credentials or external writes.\n\n## Bottom Line\n\nOpenClaw now applies bounded successful JSON reads to OpenRouter OAuth exchange and Discord webhook response paths. It is a narrow hardening change, but it protects exactly the kind of provider-controlled boundary that should never rely on unlimited buffering.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98098\">PR #98098, \"fix(providers): bound successful OAuth and webhook responses\"</a>, closing two remaining unbounded JSON response paths in provider-controlled flows.</p><p>The merged change covers successful Discord webhook execution responses and OpenRouter OAuth code exchange responses. Both now use OpenClaw's shared provider JSON response reader so oversized streams can be rejected and canceled instead of buffered without a bound.</p><p>This is a P2 fix, but it carries auth-provider and message-delivery risk labels. That combination is worth watching because the affected paths sit directly on provider and channel boundaries.</p><h2>What Changed</h2><p>The PR moves the remaining successful JSON reads to <code>readProviderJsonResponse</code>, the shared helper used to apply a response cap. The author notes that the original Google path was removed from scope because <code>fetchWithTimeout</code> already applies the same 16 MiB response cap, and the proposed Nextcloud path had already been fixed on <code>main</code>.</p><p>The Discord side keeps its existing transport contract. Discord webhook sends using <code>wait=false</code> can return <code>204</code> with no body, and optional response bodies after successful non-idempotent posts can be absent, malformed, or oversized without turning the already-completed send into an error that might trigger a duplicate bot fallback.</p><p>The OpenRouter OAuth side now rejects and cancels oversized successful responses during code exchange. That prevents a hostile or broken endpoint from forcing OpenClaw to buffer an unbounded body on a credential-adjacent path.</p><h2>Why It Matters</h2><p>OpenClaw has been steadily tightening provider and channel response handling. Error responses are not the only risk. A successful response can still be oversized, malformed, or controlled by infrastructure outside the user's machine.</p><p>That matters for OAuth because credential flows should have predictable memory and parsing behavior. It also matters for Discord because message delivery paths must avoid both silent resource hazards and accidental duplicate sends.</p><p>The subtle part of this PR is that it hardens reads without changing the success semantics for Discord. OpenClaw can cancel an oversized optional body while still treating the non-idempotent webhook send as complete, avoiding a fallback message that could make users see two bot replies.</p><h2>Validation</h2><p>The PR reports a focused Blacksmith Testbox run covering formatting plus 12 Discord webhook tests and 9 OpenRouter OAuth tests. A changed gate also passed extension typechecks, test typechecks, lint, dependency guards, database-first guard, sidecar checks, and import-cycle checks.</p><p>The oversized-stream tests verify rejection and cancellation for OpenRouter, plus cancellation without duplicate-send failure for Discord. The author also ran unauthenticated live probes against current Discord, OpenRouter, and Google JSON error endpoints without using credentials or external writes.</p><h2>Bottom Line</h2><p>OpenClaw now applies bounded successful JSON reads to OpenRouter OAuth exchange and Discord webhook response paths. It is a narrow hardening change, but it protects exactly the kind of provider-controlled boundary that should never rely on unlimited buffering.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-provider-response-bounds.png\" alt=\"OpenClaw Bounds OAuth and Webhook Responses\" /></p>",
      "date_published": "2026-07-06T08:04:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Memory",
        "Bounds",
        "Oauth",
        "Webhook",
        "Responses"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-provider-response-bounds.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-provider-response-bounds.png",
          "mime_type": "image/png",
          "title": "OpenClaw Bounds OAuth and Webhook Responses cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-sessions-send-failure-notices/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-sessions-send-failure-notices/",
      "title": "OpenClaw sessions_send Now Reports Late Failures",
      "summary": "OpenClaw now notifies requester agents when an accepted sessions_send later fails during target session delivery.",
      "content_text": "OpenClaw merged [PR #99907, \"fix: notify requester when sessions_send delivery later fails\"](https://github.com/openclaw/openclaw/pull/99907), a P1 agent-runtime fix for a confusing failure mode in agent-to-agent messaging.\n\nThe issue affected `sessions_send`, where one agent sends work or context to another session. In some cases, the caller could receive an accepted result with pending delivery, but the target run would later fail while waiting on the target session file lock.\n\nBefore this fix, that late failure was only logged. The requesting agent had no signal that the delivery failed, so it could keep operating as if the target session had received the message.\n\n## What Changed\n\nOpenClaw keeps the existing fire-and-forget contract. A `sessions_send` call can still return accepted with pending delivery when the target run has been launched but delivery has not fully completed.\n\nThe difference is what happens afterward. When the background agent-to-agent flow sees a concrete delivery or persistence failure, such as `SessionWriteLockTimeoutError`, it now notifies the requester agent.\n\nThe PR is intentionally scoped. Waited sends that already returned the error inline do not get duplicate requester turns. Recoverable wait interruptions, including gateway disconnects where delivery is unknown, remain silent.\n\nThat boundary matters because not every interrupted wait means failure. The new behavior is reserved for cases where OpenClaw knows the previously accepted send did not actually reach the target.\n\n## Why It Matters\n\nAgent-to-agent messaging has to be transparent about delivery state. If a requester sees \"accepted\" and nothing else, it can reasonably assume the other session got the handoff. When that assumption is false, downstream behavior gets messy: retries do not happen, fallback routes are skipped, and the user may never see why a workflow stalled.\n\nThis fix gives requester agents something actionable. They can retry, choose a different route, or report the failed handoff instead of silently losing a cross-session message.\n\nIt also improves OpenClaw's reliability story without changing public APIs. The PR notes there is no new model-facing parameter, config option, storage surface, or public API change.\n\n## Validation\n\nThe PR reports focused test coverage for the send tool and A2A flow:\n\n- 22 `sessions-send-tool.a2a` tests passed.\n- 35 `openclaw-tools.sessions` tests passed.\n- Formatting, linting, `git diff --check`, and local autoreview completed cleanly.\n\nThe author also included redacted local behavior proof using the real `createSessionsSendTool` entrypoint, real A2A flow, real `runAgentStep`, and a controlled Gateway RPC stub. The proof shows an initial accepted result, a delayed target wait failure, and a requester notification that includes the lock-timeout signal.\n\n## Bottom Line\n\n`sessions_send` now tells the requester when a previously accepted delivery later fails for a concrete reason. That closes a silent gap in cross-agent workflows and gives agents a chance to recover instead of assuming a message arrived.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99907\">PR #99907, \"fix: notify requester when sessions_send delivery later fails\"</a>, a P1 agent-runtime fix for a confusing failure mode in agent-to-agent messaging.</p><p>The issue affected <code>sessions_send</code>, where one agent sends work or context to another session. In some cases, the caller could receive an accepted result with pending delivery, but the target run would later fail while waiting on the target session file lock.</p><p>Before this fix, that late failure was only logged. The requesting agent had no signal that the delivery failed, so it could keep operating as if the target session had received the message.</p><h2>What Changed</h2><p>OpenClaw keeps the existing fire-and-forget contract. A <code>sessions_send</code> call can still return accepted with pending delivery when the target run has been launched but delivery has not fully completed.</p><p>The difference is what happens afterward. When the background agent-to-agent flow sees a concrete delivery or persistence failure, such as <code>SessionWriteLockTimeoutError</code>, it now notifies the requester agent.</p><p>The PR is intentionally scoped. Waited sends that already returned the error inline do not get duplicate requester turns. Recoverable wait interruptions, including gateway disconnects where delivery is unknown, remain silent.</p><p>That boundary matters because not every interrupted wait means failure. The new behavior is reserved for cases where OpenClaw knows the previously accepted send did not actually reach the target.</p><h2>Why It Matters</h2><p>Agent-to-agent messaging has to be transparent about delivery state. If a requester sees \"accepted\" and nothing else, it can reasonably assume the other session got the handoff. When that assumption is false, downstream behavior gets messy: retries do not happen, fallback routes are skipped, and the user may never see why a workflow stalled.</p><p>This fix gives requester agents something actionable. They can retry, choose a different route, or report the failed handoff instead of silently losing a cross-session message.</p><p>It also improves OpenClaw's reliability story without changing public APIs. The PR notes there is no new model-facing parameter, config option, storage surface, or public API change.</p><h2>Validation</h2><p>The PR reports focused test coverage for the send tool and A2A flow:</p><ul><li>22 <code>sessions-send-tool.a2a</code> tests passed.</li><li>35 <code>openclaw-tools.sessions</code> tests passed.</li><li>Formatting, linting, <code>git diff --check</code>, and local autoreview completed cleanly.</li></ul><p>The author also included redacted local behavior proof using the real <code>createSessionsSendTool</code> entrypoint, real A2A flow, real <code>runAgentStep</code>, and a controlled Gateway RPC stub. The proof shows an initial accepted result, a delayed target wait failure, and a requester notification that includes the lock-timeout signal.</p><h2>Bottom Line</h2><p><code>sessions_send</code> now tells the requester when a previously accepted delivery later fails for a concrete reason. That closes a silent gap in cross-agent workflows and gives agents a chance to recover instead of assuming a message arrived.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-sessions-send-failure-notices.png\" alt=\"OpenClaw sessions_send Now Reports Late Failures\" /></p>",
      "date_published": "2026-07-06T08:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Sessions",
        "Send",
        "Reports",
        "Late",
        "Failures"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-sessions-send-failure-notices.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-sessions-send-failure-notices.png",
          "mime_type": "image/png",
          "title": "OpenClaw sessions_send Now Reports Late Failures cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-6-codex-json-rpc-errors/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-6-codex-json-rpc-errors/",
      "title": "OpenClaw Codex Errors Now Return JSON-RPC Codes",
      "summary": "OpenClaw now returns valid JSON-RPC error codes when Codex app-server request handlers fail during auth refresh.",
      "content_text": "OpenClaw merged [PR #100713, \"fix(codex): return JSON-RPC codes for handler errors\"](https://github.com/openclaw/openclaw/pull/100713), a P1 Codex integration fix for a small protocol detail with a real user-facing cost.\n\nThe bug appeared when the Codex app-server asked OpenClaw to refresh ChatGPT auth tokens and the server-side handler failed. OpenClaw preserved the error message, but the serialized JSON-RPC error response did not include a numeric `error.code`.\n\nThat omission made the response malformed from Codex's point of view. Instead of seeing the underlying reauthentication failure, users could hit a generic timeout such as an auth refresh request timing out after 10 seconds.\n\n## What Changed\n\nThe fix adds a standard JSON-RPC internal-error code, `-32603`, to server-request handler failure responses. It keeps the original handler error message in the payload and adds diagnostic logging for the failed server request method and id.\n\nThat means OpenClaw is not just saying \"something went wrong.\" It is now returning a protocol-valid error object that downstream Codex clients can parse and handle as an actual failure from the auth bridge.\n\nThe PR also adds a regression test for a failing `account/chatgptAuthTokens/refresh` server-request handler, which is the path that made the issue visible.\n\n## Why It Matters\n\nAuthentication failures need to be boring and precise. A timeout pushes users toward the wrong diagnosis: flaky networking, a stuck server, or a long-running background request. A valid JSON-RPC error lets the system surface the reauthentication issue closer to where it actually happened.\n\nFor OpenClaw users who run Codex through app-server flows, this improves the handoff between two layers that both need strict protocol behavior. The OpenClaw side can fail honestly, and the Codex side no longer has to reject the response as malformed before it can explain the real problem.\n\nIt is also the kind of fix that matters more as OpenClaw grows more app integrations. Server-initiated requests are only useful if failures can cross the boundary with enough structure for the other side to recover, retry, or ask the user to act.\n\n## Validation\n\nThe PR reports targeted Codex app-server coverage:\n\n- 29 tests passed for `extensions/codex/src/app-server/client.test.ts`.\n- 110 tests passed across the client, shared-client, and auth-bridge suites.\n- `git diff --check` passed.\n- A local diff secret scan for token-like patterns passed.\n\nThe regression test verifies that handler exceptions serialize with `error.code: -32603` and preserve the original handler error message.\n\n## Bottom Line\n\nOpenClaw's Codex app-server bridge now sends valid JSON-RPC errors when handler failures occur. Users should see clearer auth-refresh failures instead of generic timeout noise, and Codex clients get the structured error payload they expect.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100713\">PR #100713, \"fix(codex): return JSON-RPC codes for handler errors\"</a>, a P1 Codex integration fix for a small protocol detail with a real user-facing cost.</p><p>The bug appeared when the Codex app-server asked OpenClaw to refresh ChatGPT auth tokens and the server-side handler failed. OpenClaw preserved the error message, but the serialized JSON-RPC error response did not include a numeric <code>error.code</code>.</p><p>That omission made the response malformed from Codex's point of view. Instead of seeing the underlying reauthentication failure, users could hit a generic timeout such as an auth refresh request timing out after 10 seconds.</p><h2>What Changed</h2><p>The fix adds a standard JSON-RPC internal-error code, <code>-32603</code>, to server-request handler failure responses. It keeps the original handler error message in the payload and adds diagnostic logging for the failed server request method and id.</p><p>That means OpenClaw is not just saying \"something went wrong.\" It is now returning a protocol-valid error object that downstream Codex clients can parse and handle as an actual failure from the auth bridge.</p><p>The PR also adds a regression test for a failing <code>account/chatgptAuthTokens/refresh</code> server-request handler, which is the path that made the issue visible.</p><h2>Why It Matters</h2><p>Authentication failures need to be boring and precise. A timeout pushes users toward the wrong diagnosis: flaky networking, a stuck server, or a long-running background request. A valid JSON-RPC error lets the system surface the reauthentication issue closer to where it actually happened.</p><p>For OpenClaw users who run Codex through app-server flows, this improves the handoff between two layers that both need strict protocol behavior. The OpenClaw side can fail honestly, and the Codex side no longer has to reject the response as malformed before it can explain the real problem.</p><p>It is also the kind of fix that matters more as OpenClaw grows more app integrations. Server-initiated requests are only useful if failures can cross the boundary with enough structure for the other side to recover, retry, or ask the user to act.</p><h2>Validation</h2><p>The PR reports targeted Codex app-server coverage:</p><ul><li>29 tests passed for <code>extensions/codex/src/app-server/client.test.ts</code>.</li><li>110 tests passed across the client, shared-client, and auth-bridge suites.</li><li><code>git diff --check</code> passed.</li><li>A local diff secret scan for token-like patterns passed.</li></ul><p>The regression test verifies that handler exceptions serialize with <code>error.code: -32603</code> and preserve the original handler error message.</p><h2>Bottom Line</h2><p>OpenClaw's Codex app-server bridge now sends valid JSON-RPC errors when handler failures occur. Users should see clearer auth-refresh failures instead of generic timeout noise, and Codex clients get the structured error payload they expect.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-codex-json-rpc-errors.png\" alt=\"OpenClaw Codex Errors Now Return JSON-RPC Codes\" /></p>",
      "date_published": "2026-07-06T08:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.648Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Codex",
        "Errors",
        "Return",
        "Json",
        "Codes"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-codex-json-rpc-errors.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-6-codex-json-rpc-errors.png",
          "mime_type": "image/png",
          "title": "OpenClaw Codex Errors Now Return JSON-RPC Codes cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-empty-reply-failure/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-empty-reply-failure/",
      "title": "OpenClaw Empty Replies Now Surface Safe Failures",
      "summary": "OpenClaw now sends a sanitized failure when an interactive agent turn completes without any deliverable final reply.",
      "content_text": "OpenClaw merged [PR #100456, \"fix(auto-reply): surface empty interactive completions\"](https://github.com/openclaw/openclaw/pull/100456), a P1 message-delivery fix for successful agent turns that finish without a visible reply.\n\nThe failure mode is subtle but painful. An interactive turn can complete successfully in the runtime while directive stripping, reasoning/commentary filtering, model-fallback exhaustion, queued follow-up routing, or block-stream deduplication leaves no final message that should be shown to the user.\n\nBefore this fix, the user could see a completed turn and still receive no explanation.\n\n## What Changed\n\nThe PR moves the policy to the reply-delivery owner boundary. Instead of teaching every provider, TUI path, or streaming implementation how to decide whether silence is acceptable, OpenClaw now makes the delivery layer responsible for distinguishing intentional silence from an empty failed result.\n\nDirect replies and queued follow-up paths now share safe failure copy and the same conversation-silence policy. The implementation also separates terminal delivery evidence from reasoning, commentary, status notices, and empty voice markers.\n\nThat distinction matters because OpenClaw still has legitimate no-reply cases. The PR explicitly preserves silence for `NO_REPLY`, heartbeats, pending continuations, message-tool-only runs, room or internal events, and committed side effects.\n\n## Why It Matters\n\nOpenClaw users do not care whether an empty result came from model fallback, stream block handling, directive filtering, or a channel-specific follow-up path. If an interactive request was supposed to produce a visible answer and did not, the system should say so in a controlled way.\n\nThis fix improves trust without making agents noisier. It does not convert deliberate silence into chatter. It only catches the case where a turn completed, had no deliverable reply, and would otherwise leave the user guessing.\n\nThe change is especially relevant for channel users. A chat surface makes absence feel like a routing or reliability bug. A sanitized terminal failure gives the user something actionable while protecting internal details.\n\n## Validation\n\nThe PR reports focused Testbox coverage with 236 passing tests across direct reply, queued follow-up, and block-stream suites. It also links an exact changed gate covering typecheck, lint, focused tests, and changed-surface checks.\n\nHosted CI passed at the exact head, and the author included source-blind real Gateway plus TUI PTY proof. That proof covered a visible failure, absence of the raw directive, a successful next turn, and a clean exit.\n\nThe PR also checked upstream Codex contract behavior, noting that completed turns can legitimately emit an empty item list and that `NotLoaded` is intentionally empty.\n\n## Bottom Line\n\nOpenClaw now handles empty interactive completions at the boundary users actually experience: reply delivery. When a completed turn cannot produce a visible answer, users get a safe failure instead of unexplained silence.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100456\">PR #100456, \"fix(auto-reply): surface empty interactive completions\"</a>, a P1 message-delivery fix for successful agent turns that finish without a visible reply.</p><p>The failure mode is subtle but painful. An interactive turn can complete successfully in the runtime while directive stripping, reasoning/commentary filtering, model-fallback exhaustion, queued follow-up routing, or block-stream deduplication leaves no final message that should be shown to the user.</p><p>Before this fix, the user could see a completed turn and still receive no explanation.</p><h2>What Changed</h2><p>The PR moves the policy to the reply-delivery owner boundary. Instead of teaching every provider, TUI path, or streaming implementation how to decide whether silence is acceptable, OpenClaw now makes the delivery layer responsible for distinguishing intentional silence from an empty failed result.</p><p>Direct replies and queued follow-up paths now share safe failure copy and the same conversation-silence policy. The implementation also separates terminal delivery evidence from reasoning, commentary, status notices, and empty voice markers.</p><p>That distinction matters because OpenClaw still has legitimate no-reply cases. The PR explicitly preserves silence for <code>NO_REPLY</code>, heartbeats, pending continuations, message-tool-only runs, room or internal events, and committed side effects.</p><h2>Why It Matters</h2><p>OpenClaw users do not care whether an empty result came from model fallback, stream block handling, directive filtering, or a channel-specific follow-up path. If an interactive request was supposed to produce a visible answer and did not, the system should say so in a controlled way.</p><p>This fix improves trust without making agents noisier. It does not convert deliberate silence into chatter. It only catches the case where a turn completed, had no deliverable reply, and would otherwise leave the user guessing.</p><p>The change is especially relevant for channel users. A chat surface makes absence feel like a routing or reliability bug. A sanitized terminal failure gives the user something actionable while protecting internal details.</p><h2>Validation</h2><p>The PR reports focused Testbox coverage with 236 passing tests across direct reply, queued follow-up, and block-stream suites. It also links an exact changed gate covering typecheck, lint, focused tests, and changed-surface checks.</p><p>Hosted CI passed at the exact head, and the author included source-blind real Gateway plus TUI PTY proof. That proof covered a visible failure, absence of the raw directive, a successful next turn, and a clean exit.</p><p>The PR also checked upstream Codex contract behavior, noting that completed turns can legitimately emit an empty item list and that <code>NotLoaded</code> is intentionally empty.</p><h2>Bottom Line</h2><p>OpenClaw now handles empty interactive completions at the boundary users actually experience: reply delivery. When a completed turn cannot produce a visible answer, users get a safe failure instead of unexplained silence.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-empty-reply-failure.png\" alt=\"OpenClaw Empty Replies Now Surface Safe Failures\" /></p>",
      "date_published": "2026-07-05T23:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Empty",
        "Replies",
        "Surface",
        "Safe",
        "Failures"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-empty-reply-failure.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-empty-reply-failure.png",
          "mime_type": "image/png",
          "title": "OpenClaw Empty Replies Now Surface Safe Failures cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-imessage-threaded-reply-fallback/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-imessage-threaded-reply-fallback/",
      "title": "OpenClaw iMessage Fix Protects Threaded Replies",
      "summary": "OpenClaw now falls back to plain iMessage sends when threaded replies are unsupported and scopes recovery cursors per chat database.",
      "content_text": "OpenClaw merged [PR #100446, \"fix(imessage): plain-send fallback for threaded replies + db-scoped recovery cursor\"](https://github.com/openclaw/openclaw/pull/100446), a P1 message-delivery fix for iMessage deployments that use the AppleScript transport or move between chat databases.\n\nThe PR focuses on two failure modes from a dedicated bot-user and SSH-wrapped iMessage setup. Both had the same user-facing result: OpenClaw appeared to be working, but messages could vanish at the delivery or inbound recovery boundary.\n\n## What Changed\n\nThe first fix protects outbound replies. When OpenClaw tried to send a threaded iMessage reply through a transport that did not support `reply_to`, the send path could hard-error. The PR changes that behavior so OpenClaw retries once without the thread reference and delivers the message unthreaded instead.\n\nThat fallback covers both text and media replies because both travel through the same send path. The receipt also reports the unthreaded send that actually happened, rather than pretending the original threaded reply succeeded.\n\nThe second fix scopes the iMessage downtime recovery cursor by database identity. Previously, the cursor was keyed per account. If an operator pointed `dbPath` at a different `chat.db` with lower row IDs, OpenClaw could reuse a stale high-water mark and silently skip new inbound messages.\n\nNow the cursor is keyed by account plus database identity, with local paths canonicalized so the implicit default path and explicit spellings of the same database map together.\n\n## Why It Matters\n\niMessage support often runs in real-world macOS setups with private API constraints, SSH wrapping, bot users, and database paths that change during maintenance. Those are exactly the setups where a delivery system needs graceful degradation.\n\nThreading is useful, but it is less important than delivering the answer. If the bridge cannot honor a thread reference, an unthreaded message is still a successful user-visible reply.\n\nThe database cursor change is just as important for operators. Moving between a default user database, a bot-user database, or a remote host should not permanently wedge inbound replay because an old cursor belongs to a different message store.\n\n## Validation\n\nThe PR reports 92 passing tests across the touched iMessage send, recovery-cursor, and monitor route files. It also reports clean `pnpm tsgo:extensions` and `pnpm tsgo:extensions:test` runs.\n\nThe live proof is stronger than the unit coverage alone. The author tested a real two-Mac SSH deployment, reproduced the `reply_to requires bridge transport` failure against the real `imsg` binary, and verified that stripping `reply_to` delivered through AppleScript. The same proof showed the fixed recovery cursor being re-scoped into a database-specific key.\n\n## Bottom Line\n\nOpenClaw's iMessage path now treats unsupported threading as a degradation, not a dropped reply. It also stops one chat database's recovery cursor from suppressing another database's inbound messages.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100446\">PR #100446, \"fix(imessage): plain-send fallback for threaded replies + db-scoped recovery cursor\"</a>, a P1 message-delivery fix for iMessage deployments that use the AppleScript transport or move between chat databases.</p><p>The PR focuses on two failure modes from a dedicated bot-user and SSH-wrapped iMessage setup. Both had the same user-facing result: OpenClaw appeared to be working, but messages could vanish at the delivery or inbound recovery boundary.</p><h2>What Changed</h2><p>The first fix protects outbound replies. When OpenClaw tried to send a threaded iMessage reply through a transport that did not support <code>reply_to</code>, the send path could hard-error. The PR changes that behavior so OpenClaw retries once without the thread reference and delivers the message unthreaded instead.</p><p>That fallback covers both text and media replies because both travel through the same send path. The receipt also reports the unthreaded send that actually happened, rather than pretending the original threaded reply succeeded.</p><p>The second fix scopes the iMessage downtime recovery cursor by database identity. Previously, the cursor was keyed per account. If an operator pointed <code>dbPath</code> at a different <code>chat.db</code> with lower row IDs, OpenClaw could reuse a stale high-water mark and silently skip new inbound messages.</p><p>Now the cursor is keyed by account plus database identity, with local paths canonicalized so the implicit default path and explicit spellings of the same database map together.</p><h2>Why It Matters</h2><p>iMessage support often runs in real-world macOS setups with private API constraints, SSH wrapping, bot users, and database paths that change during maintenance. Those are exactly the setups where a delivery system needs graceful degradation.</p><p>Threading is useful, but it is less important than delivering the answer. If the bridge cannot honor a thread reference, an unthreaded message is still a successful user-visible reply.</p><p>The database cursor change is just as important for operators. Moving between a default user database, a bot-user database, or a remote host should not permanently wedge inbound replay because an old cursor belongs to a different message store.</p><h2>Validation</h2><p>The PR reports 92 passing tests across the touched iMessage send, recovery-cursor, and monitor route files. It also reports clean <code>pnpm tsgo:extensions</code> and <code>pnpm tsgo:extensions:test</code> runs.</p><p>The live proof is stronger than the unit coverage alone. The author tested a real two-Mac SSH deployment, reproduced the <code>reply_to requires bridge transport</code> failure against the real <code>imsg</code> binary, and verified that stripping <code>reply_to</code> delivered through AppleScript. The same proof showed the fixed recovery cursor being re-scoped into a database-specific key.</p><h2>Bottom Line</h2><p>OpenClaw's iMessage path now treats unsupported threading as a degradation, not a dropped reply. It also stops one chat database's recovery cursor from suppressing another database's inbound messages.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-imessage-threaded-reply-fallback.png\" alt=\"OpenClaw iMessage Fix Protects Threaded Replies\" /></p>",
      "date_published": "2026-07-05T23:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Imessage",
        "Protects",
        "Threaded",
        "Replies"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-imessage-threaded-reply-fallback.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-imessage-threaded-reply-fallback.png",
          "mime_type": "image/png",
          "title": "OpenClaw iMessage Fix Protects Threaded Replies cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-beta-2-release/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-beta-2-release/",
      "title": "OpenClaw 2026.7.1 Beta 2 Broadens Workflows",
      "summary": "OpenClaw 2026.7.1-beta.2 adds GPT-5.6 support, OpenClaw attach, Telegram Codex flows, mobile updates, and release proof.",
      "content_text": "OpenClaw published [v2026.7.1-beta.2](https://github.com/openclaw/openclaw/releases/tag/v2026.7.1-beta.2) on July 5, giving testers a broad beta that spans models, cron, Telegram Codex workflows, native apps, messaging, and Control UI navigation.\n\nThe release notes are large, but the shape is clear: OpenClaw is tightening the operator experience around active work. More surfaces can start, steer, resume, or inspect agent sessions without dropping the safety and recovery contracts that recent releases have been reinforcing.\n\n## What Leads The Release\n\nThe headline model item is OpenAI GPT-5.6 support. The release says OpenClaw now recognizes the GPT-5.6 family across the model catalog, capability checks, and runtime selection paths through PR #98333.\n\nFor CLI and harness workflows, `openclaw attach` is now part of the beta. The release describes it as a way to launch an external harness against an existing Gateway session, making Codex-style workflows easier to resume and inspect.\n\nCron also gets a bigger role. The new `on-exit` schedule kind can wake an agent when a watched command exits, while detached session-targeted runs continue the recent push toward more explicit background automation.\n\n## Channel And App Updates\n\nTelegram is one of the most visible channel winners in this beta. The release highlights Codex pairing through `/login`, steering active Codex runs, and recovery of final replies across transient API failures.\n\niMessage gains native poll creation, reading, and voting. Signal gains target aliases. Built-in usage footers also give chat users clearer per-turn accounting, which matters when agent work crosses several tools or model calls.\n\nThe native app work is just as broad. The release notes call out iOS visual-system updates across Chat, Talk, onboarding, and reconnect flows; localization across Apple and Android surfaces; and macOS local Gateway installation so the Mac app can reduce manual setup before first use.\n\n## Control UI And Operator Visibility\n\nThe Control UI changes continue the recent move toward session-first operation. This beta includes a session-first sidebar, compact context meter, warm light theme, reasoning-effort slider, streamlined composer, and slash-command picker.\n\nThose interface changes are not just polish. They make active conversations, command entry, and model/reasoning controls easier to reach during repeated daily use.\n\nThe release also lists richer diagnostics, including auth-profile, workspace, device-pairing, channel-plugin, memory-provider, systemd exhaustion, and Windows LAN firewall findings.\n\n## Verification\n\nThe release includes direct verification links for the npm beta package, registry tarball, release SHA, full release CI report, release publish, npm preflight, full validation, plugin npm publish, plugin ClawHub publish dispatch, and OpenClaw npm publish.\n\nThat proof trail matters because this beta crosses many runtime surfaces at once. A release with model support, native apps, channels, cron, providers, diagnostics, and marketplace publishing needs more than a changelog.\n\n## Bottom Line\n\nOpenClaw 2026.7.1-beta.2 is a broad workflow beta. The important story is not one single feature. It is the way the release connects model selection, session attachment, Telegram Codex control, event-driven cron, native app onboarding, and Control UI navigation into a more coherent operator loop.",
      "content_html": "<p>OpenClaw published <a href=\"https://github.com/openclaw/openclaw/releases/tag/v2026.7.1-beta.2\">v2026.7.1-beta.2</a> on July 5, giving testers a broad beta that spans models, cron, Telegram Codex workflows, native apps, messaging, and Control UI navigation.</p><p>The release notes are large, but the shape is clear: OpenClaw is tightening the operator experience around active work. More surfaces can start, steer, resume, or inspect agent sessions without dropping the safety and recovery contracts that recent releases have been reinforcing.</p><h2>What Leads The Release</h2><p>The headline model item is OpenAI GPT-5.6 support. The release says OpenClaw now recognizes the GPT-5.6 family across the model catalog, capability checks, and runtime selection paths through PR #98333.</p><p>For CLI and harness workflows, <code>openclaw attach</code> is now part of the beta. The release describes it as a way to launch an external harness against an existing Gateway session, making Codex-style workflows easier to resume and inspect.</p><p>Cron also gets a bigger role. The new <code>on-exit</code> schedule kind can wake an agent when a watched command exits, while detached session-targeted runs continue the recent push toward more explicit background automation.</p><h2>Channel And App Updates</h2><p>Telegram is one of the most visible channel winners in this beta. The release highlights Codex pairing through <code>/login</code>, steering active Codex runs, and recovery of final replies across transient API failures.</p><p>iMessage gains native poll creation, reading, and voting. Signal gains target aliases. Built-in usage footers also give chat users clearer per-turn accounting, which matters when agent work crosses several tools or model calls.</p><p>The native app work is just as broad. The release notes call out iOS visual-system updates across Chat, Talk, onboarding, and reconnect flows; localization across Apple and Android surfaces; and macOS local Gateway installation so the Mac app can reduce manual setup before first use.</p><h2>Control UI And Operator Visibility</h2><p>The Control UI changes continue the recent move toward session-first operation. This beta includes a session-first sidebar, compact context meter, warm light theme, reasoning-effort slider, streamlined composer, and slash-command picker.</p><p>Those interface changes are not just polish. They make active conversations, command entry, and model/reasoning controls easier to reach during repeated daily use.</p><p>The release also lists richer diagnostics, including auth-profile, workspace, device-pairing, channel-plugin, memory-provider, systemd exhaustion, and Windows LAN firewall findings.</p><h2>Verification</h2><p>The release includes direct verification links for the npm beta package, registry tarball, release SHA, full release CI report, release publish, npm preflight, full validation, plugin npm publish, plugin ClawHub publish dispatch, and OpenClaw npm publish.</p><p>That proof trail matters because this beta crosses many runtime surfaces at once. A release with model support, native apps, channels, cron, providers, diagnostics, and marketplace publishing needs more than a changelog.</p><h2>Bottom Line</h2><p>OpenClaw 2026.7.1-beta.2 is a broad workflow beta. The important story is not one single feature. It is the way the release connects model selection, session attachment, Telegram Codex control, event-driven cron, native app onboarding, and Control UI navigation into a more coherent operator loop.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-beta-2-release.png\" alt=\"OpenClaw 2026.7.1 Beta 2 Broadens Workflows\" /></p>",
      "date_published": "2026-07-05T23:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "Memory",
        "2026",
        "Beta",
        "Broadens",
        "Workflows"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-beta-2-release.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-beta-2-release.png",
          "mime_type": "image/png",
          "title": "OpenClaw 2026.7.1 Beta 2 Broadens Workflows cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-macos-ssh-helper-path/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-macos-ssh-helper-path/",
      "title": "OpenClaw Mac SSH Tunnels Keep Helper Paths",
      "summary": "OpenClaw for macOS now preserves SSH helper paths and inherited connection state, improving remote Gateway launches from Finder.",
      "content_text": "OpenClaw merged [PR #100214, \"fix(macos): preserve PATH for SSH helpers\"](https://github.com/openclaw/openclaw/pull/100214), a macOS app fix for remote Gateway connections that rely on SSH helper commands.\n\nThe issue shows up when OpenClaw starts from Finder or another sanitized GUI environment. In those launches, the process may not inherit the same `PATH` a user expects from an interactive shell. SSH aliases that rely on bare `ProxyCommand` helpers can then fail because the helper command is not resolvable.\n\nFor users who connect OpenClaw to a remote Gateway through SSH aliases, that makes the Mac app feel unreliable even when the alias works perfectly in Terminal.\n\n## What Changed\n\nThe macOS app now gives SSH preflight and tunnel processes an app-managed command path. That path includes OpenClaw's preferred command locations and now also includes the conventional user-local bin directory after system paths.\n\nThe PR also preserves inherited connection state such as `HOME` and `SSH_AUTH_SOCK`. That matters because SSH helpers and agents frequently depend on those values. Replacing the whole environment would solve one problem while creating another.\n\nThe change touches the macOS command resolver, remote Gateway probe, remote port tunnel setup, and focused tests. The changelog describes the user-facing effect directly: macOS SSH tunnels now resolve user-installed `ProxyCommand` helpers through the app's managed `PATH` while preserving inherited connection environment.\n\n## Why It Matters\n\nOpenClaw's native Mac app is increasingly responsible for making local and remote agent setups feel approachable. Remote Gateway support is a big part of that, especially for operators who keep the heavy runtime on another machine and use the Mac app as the client.\n\nSSH aliases are the natural way many developers encode that setup. They may include bastion hosts, `ProxyCommand`, user-local helper binaries, or agent sockets. If those aliases only work from a login shell, the GUI app becomes a second-class path.\n\nThis fix narrows that gap. A remote alias that depends on common user-local helpers should now work when the app launches from Finder, not just when started from a shell with a hand-built environment.\n\n## Validation\n\nThe PR reports 27 focused Swift tests through:\n\n`swift test --filter 'RemotePortTunnelTests|CommandResolverTests'`\n\nIt also reports SwiftFormat lint on the touched Swift files. Beyond unit tests, the packaged app was launched with a system-only `PATH`, then used to verify that an SSH alias established its tunnel and the Gateway readiness probe succeeded.\n\nThe added tests check two important pieces of behavior: preferred paths include the user-local bin directory once, after system bins, and the SSH environment replaces stale `PATH` values without dropping inherited values such as `HOME` and `SSH_AUTH_SOCK`.\n\n## Bottom Line\n\nOpenClaw for macOS is getting better at acting like the environment users already configured. SSH aliases with helper commands should be less fragile when the app starts from ordinary GUI launch paths.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100214\">PR #100214, \"fix(macos): preserve PATH for SSH helpers\"</a>, a macOS app fix for remote Gateway connections that rely on SSH helper commands.</p><p>The issue shows up when OpenClaw starts from Finder or another sanitized GUI environment. In those launches, the process may not inherit the same <code>PATH</code> a user expects from an interactive shell. SSH aliases that rely on bare <code>ProxyCommand</code> helpers can then fail because the helper command is not resolvable.</p><p>For users who connect OpenClaw to a remote Gateway through SSH aliases, that makes the Mac app feel unreliable even when the alias works perfectly in Terminal.</p><h2>What Changed</h2><p>The macOS app now gives SSH preflight and tunnel processes an app-managed command path. That path includes OpenClaw's preferred command locations and now also includes the conventional user-local bin directory after system paths.</p><p>The PR also preserves inherited connection state such as <code>HOME</code> and <code>SSH_AUTH_SOCK</code>. That matters because SSH helpers and agents frequently depend on those values. Replacing the whole environment would solve one problem while creating another.</p><p>The change touches the macOS command resolver, remote Gateway probe, remote port tunnel setup, and focused tests. The changelog describes the user-facing effect directly: macOS SSH tunnels now resolve user-installed <code>ProxyCommand</code> helpers through the app's managed <code>PATH</code> while preserving inherited connection environment.</p><h2>Why It Matters</h2><p>OpenClaw's native Mac app is increasingly responsible for making local and remote agent setups feel approachable. Remote Gateway support is a big part of that, especially for operators who keep the heavy runtime on another machine and use the Mac app as the client.</p><p>SSH aliases are the natural way many developers encode that setup. They may include bastion hosts, <code>ProxyCommand</code>, user-local helper binaries, or agent sockets. If those aliases only work from a login shell, the GUI app becomes a second-class path.</p><p>This fix narrows that gap. A remote alias that depends on common user-local helpers should now work when the app launches from Finder, not just when started from a shell with a hand-built environment.</p><h2>Validation</h2><p>The PR reports 27 focused Swift tests through:</p><p><code>swift test --filter 'RemotePortTunnelTests|CommandResolverTests'</code></p><p>It also reports SwiftFormat lint on the touched Swift files. Beyond unit tests, the packaged app was launched with a system-only <code>PATH</code>, then used to verify that an SSH alias established its tunnel and the Gateway readiness probe succeeded.</p><p>The added tests check two important pieces of behavior: preferred paths include the user-local bin directory once, after system bins, and the SSH environment replaces stale <code>PATH</code> values without dropping inherited values such as <code>HOME</code> and <code>SSH_AUTH_SOCK</code>.</p><h2>Bottom Line</h2><p>OpenClaw for macOS is getting better at acting like the environment users already configured. SSH aliases with helper commands should be less fragile when the app starts from ordinary GUI launch paths.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-macos-ssh-helper-path.png\" alt=\"OpenClaw Mac SSH Tunnels Keep Helper Paths\" /></p>",
      "date_published": "2026-07-05T08:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Tunnels",
        "Keep",
        "Helper",
        "Paths"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-macos-ssh-helper-path.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-macos-ssh-helper-path.png",
          "mime_type": "image/png",
          "title": "OpenClaw Mac SSH Tunnels Keep Helper Paths cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-discord-voice-text-fallback/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-discord-voice-text-fallback/",
      "title": "OpenClaw Discord Voice Replies Fall Back to Text",
      "summary": "OpenClaw now sends visible Discord text when voice-note delivery fails, preventing final replies from disappearing silently.",
      "content_text": "OpenClaw merged [PR #89962, \"fix(discord): fall back to text when voice delivery fails\"](https://github.com/openclaw/openclaw/pull/89962), a Discord delivery fix focused on one frustrating failure mode: a final answer that was generated, routed, and then lost when voice-note delivery failed.\n\nThe PR describes a real local OpenClaw Discord setup where a final reply attempted to go out as a voice note. When the voice path failed, no visible text fallback was sent. From the user's perspective, the agent simply never answered.\n\n## What Changed\n\nThe Discord outbound path still tries voice-note delivery first when `audioAsVoice` is enabled. The difference is what happens after a failure.\n\nIf voice delivery rejects and visible text is available, OpenClaw now sends that text to Discord. If the visible text was previously stripped into a hidden text-to-speech supplement, OpenClaw can use that supplement as the fallback text instead.\n\nThe change is intentionally scoped to the Discord payload path. It does not redesign media sending, voice conversion, or unrelated voice behavior. It only covers the final payload boundary where a voice reply is attempted and then fails before the user sees anything.\n\n## Why The Edge Case Matters\n\nVoice replies are a nice channel feature, but they are not more important than answer delivery. Discord voice-note conversion can fail for ordinary operational reasons: audio conversion errors, missing or misbehaving media tooling, invalid inputs, or runtime environment differences.\n\nBefore this PR, a failure at that point could swallow the entire final reply. That is worse than a degraded experience. It breaks trust because the agent did the work but the channel never shows the result.\n\nThe new fallback behavior changes the priority order:\n\n- Prefer the voice-note experience when it succeeds.\n- Preserve the reply target when falling back.\n- Avoid duplicate text when a supplement was already delivered visibly.\n- Send plain text rather than dropping the answer.\n\nThat is the right tradeoff for a messaging integration. A text answer is still an answer.\n\n## Validation\n\nThe PR includes live behavior proof from a real Discord bot and private test channel. The patched path was run with `audioAsVoice: true`, visible fallback text, and deliberately invalid audio input so the voice conversion step failed.\n\nAfter the forced voice failure, OpenClaw posted the fallback text. Fetching the message back from Discord returned status 200, matching content, zero attachments, and a normal message type. That confirmed the result was a text fallback rather than a voice attachment.\n\nThe test suite now covers four regression cases:\n\n- falling back to visible text when Discord voice delivery rejects\n- falling back to hidden TTS supplement text when visible text was stripped for voice delivery\n- preserving the reply target during fallback\n- suppressing duplicate TTS supplement text when it was already visibly delivered\n\nThe author also reports `CI=true pnpm test extensions/discord/src/outbound-adapter.test.ts`, TypeScript checking, `pnpm test:extension discord`, and a clean Codex review.\n\n## Bottom Line\n\nOpenClaw's Discord voice mode now fails softer. If a voice note cannot be delivered, users should still see the final answer as text instead of wondering whether the agent vanished.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/89962\">PR #89962, \"fix(discord): fall back to text when voice delivery fails\"</a>, a Discord delivery fix focused on one frustrating failure mode: a final answer that was generated, routed, and then lost when voice-note delivery failed.</p><p>The PR describes a real local OpenClaw Discord setup where a final reply attempted to go out as a voice note. When the voice path failed, no visible text fallback was sent. From the user's perspective, the agent simply never answered.</p><h2>What Changed</h2><p>The Discord outbound path still tries voice-note delivery first when <code>audioAsVoice</code> is enabled. The difference is what happens after a failure.</p><p>If voice delivery rejects and visible text is available, OpenClaw now sends that text to Discord. If the visible text was previously stripped into a hidden text-to-speech supplement, OpenClaw can use that supplement as the fallback text instead.</p><p>The change is intentionally scoped to the Discord payload path. It does not redesign media sending, voice conversion, or unrelated voice behavior. It only covers the final payload boundary where a voice reply is attempted and then fails before the user sees anything.</p><h2>Why The Edge Case Matters</h2><p>Voice replies are a nice channel feature, but they are not more important than answer delivery. Discord voice-note conversion can fail for ordinary operational reasons: audio conversion errors, missing or misbehaving media tooling, invalid inputs, or runtime environment differences.</p><p>Before this PR, a failure at that point could swallow the entire final reply. That is worse than a degraded experience. It breaks trust because the agent did the work but the channel never shows the result.</p><p>The new fallback behavior changes the priority order:</p><ul><li>Prefer the voice-note experience when it succeeds.</li><li>Preserve the reply target when falling back.</li><li>Avoid duplicate text when a supplement was already delivered visibly.</li><li>Send plain text rather than dropping the answer.</li></ul><p>That is the right tradeoff for a messaging integration. A text answer is still an answer.</p><h2>Validation</h2><p>The PR includes live behavior proof from a real Discord bot and private test channel. The patched path was run with <code>audioAsVoice: true</code>, visible fallback text, and deliberately invalid audio input so the voice conversion step failed.</p><p>After the forced voice failure, OpenClaw posted the fallback text. Fetching the message back from Discord returned status 200, matching content, zero attachments, and a normal message type. That confirmed the result was a text fallback rather than a voice attachment.</p><p>The test suite now covers four regression cases:</p><ul><li>falling back to visible text when Discord voice delivery rejects</li><li>falling back to hidden TTS supplement text when visible text was stripped for voice delivery</li><li>preserving the reply target during fallback</li><li>suppressing duplicate TTS supplement text when it was already visibly delivered</li></ul><p>The author also reports <code>CI=true pnpm test extensions/discord/src/outbound-adapter.test.ts</code>, TypeScript checking, <code>pnpm test:extension discord</code>, and a clean Codex review.</p><h2>Bottom Line</h2><p>OpenClaw's Discord voice mode now fails softer. If a voice note cannot be delivered, users should still see the final answer as text instead of wondering whether the agent vanished.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-discord-voice-text-fallback.png\" alt=\"OpenClaw Discord Voice Replies Fall Back to Text\" /></p>",
      "date_published": "2026-07-05T08:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Discord",
        "Voice",
        "Replies",
        "Fall",
        "Back"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-discord-voice-text-fallback.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-discord-voice-text-fallback.png",
          "mime_type": "image/png",
          "title": "OpenClaw Discord Voice Replies Fall Back to Text cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-5-cron-toolsallow-marker/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-5-cron-toolsallow-marker/",
      "title": "OpenClaw Cron Edits Stop Breaking CLI Runs",
      "summary": "OpenClaw now preserves default tool policy markers when scheduled jobs are edited, preventing CLI backend cron runs from failing later.",
      "content_text": "OpenClaw merged [PR #100203, \"fix(cron): job edits no longer break CLI-backend runs by stripping the default toolsAllow marker\"](https://github.com/openclaw/openclaw/pull/100203), a small but important reliability fix for scheduled jobs that run through CLI backends.\n\nThe failure mode was surprisingly sharp. A cron job could be created with OpenClaw's default tool inventory, run correctly, then start failing after an unrelated edit to the job. The edit did not need to touch tools at all. In the production trace cited by the PR, an agent edited its own scheduled job prompt text and every later run failed until the payload was manually repaired.\n\nThe error was explicit: `CLI backend claude-cli cannot enforce runtime toolsAllow; use an embedded runtime for restricted tool policy`.\n\n## What Went Wrong\n\nOpenClaw cron jobs created through the cron tool receive the default tool list in `payload.toolsAllow`. That list is marked internally with `toolsAllowIsDefault: true`, which tells later runtime code that the list is a default snapshot rather than a user-authored restriction.\n\nThat marker matters because CLI backends cannot enforce arbitrary runtime tool restrictions. OpenClaw intentionally fails closed when it sees an explicit restricted list on a backend that cannot enforce it.\n\nThe bug lived in the edit path. The cron tool's model-facing schema did not expose the default marker. When an agent edited a job, it could echo the unchanged tool list back without the marker. OpenClaw then treated the unchanged default list as a new explicit restriction. The next CLI-backed run correctly refused to start.\n\n## The Fix\n\nThe new behavior preserves the default marker when an edit leaves the list unchanged. In other words, the same default list can no longer be silently reclassified as an explicit restriction just because the model-facing patch omitted an internal flag.\n\nThe PR keeps the important safety boundaries intact:\n\n- An unchanged default-stamped list remains a default.\n- A genuinely changed list still becomes an explicit choice.\n- `toolsAllow: null` still clears both the list and marker.\n- Kind replacements still need the stamped marker on the patch itself.\n- The fail-closed CLI guard remains in place.\n\nThat last point is the key security detail. OpenClaw is not making CLI backends pretend they can enforce restricted tool policy. It is only preventing ordinary job edits from corrupting the meaning of the existing default policy.\n\n## Why It Matters\n\nScheduled jobs are often edited by agents themselves: prompt tweaks, timing adjustments, delivery target changes, or small workflow refinements. If those edits can break future runs without touching the tool policy, cron becomes fragile in exactly the place it should be dependable.\n\nThis fix restores the expected contract. Editing a scheduled job's message or prompt should not change whether the runtime considers its tool list default or restricted.\n\nIt also protects a useful operator workflow: CLI-backed scheduled jobs can continue using default tool access while still rejecting explicit restricted policies that the backend cannot enforce.\n\n## Validation\n\nThe PR reports a fail-confirmed regression in `service.jobs.test.ts`: before the fix, a patch with an unchanged list, changed message, and missing marker failed. After the fix, the combined jobs and run-executor message-tool-policy suites passed 132 tests.\n\nAn executor-level test also asserts that the CLI run context no longer throws for the repaired default-marker case. Lint and whitespace checks were clean, and the PR landed after manual orchestrator review.\n\n## Bottom Line\n\nOpenClaw cron edits are now less brittle. Agents and operators can adjust scheduled jobs without accidentally turning a default tool inventory into an unenforceable explicit restriction that stops future CLI backend runs.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100203\">PR #100203, \"fix(cron): job edits no longer break CLI-backend runs by stripping the default toolsAllow marker\"</a>, a small but important reliability fix for scheduled jobs that run through CLI backends.</p><p>The failure mode was surprisingly sharp. A cron job could be created with OpenClaw's default tool inventory, run correctly, then start failing after an unrelated edit to the job. The edit did not need to touch tools at all. In the production trace cited by the PR, an agent edited its own scheduled job prompt text and every later run failed until the payload was manually repaired.</p><p>The error was explicit: <code>CLI backend claude-cli cannot enforce runtime toolsAllow; use an embedded runtime for restricted tool policy</code>.</p><h2>What Went Wrong</h2><p>OpenClaw cron jobs created through the cron tool receive the default tool list in <code>payload.toolsAllow</code>. That list is marked internally with <code>toolsAllowIsDefault: true</code>, which tells later runtime code that the list is a default snapshot rather than a user-authored restriction.</p><p>That marker matters because CLI backends cannot enforce arbitrary runtime tool restrictions. OpenClaw intentionally fails closed when it sees an explicit restricted list on a backend that cannot enforce it.</p><p>The bug lived in the edit path. The cron tool's model-facing schema did not expose the default marker. When an agent edited a job, it could echo the unchanged tool list back without the marker. OpenClaw then treated the unchanged default list as a new explicit restriction. The next CLI-backed run correctly refused to start.</p><h2>The Fix</h2><p>The new behavior preserves the default marker when an edit leaves the list unchanged. In other words, the same default list can no longer be silently reclassified as an explicit restriction just because the model-facing patch omitted an internal flag.</p><p>The PR keeps the important safety boundaries intact:</p><ul><li>An unchanged default-stamped list remains a default.</li><li>A genuinely changed list still becomes an explicit choice.</li><li><code>toolsAllow: null</code> still clears both the list and marker.</li><li>Kind replacements still need the stamped marker on the patch itself.</li><li>The fail-closed CLI guard remains in place.</li></ul><p>That last point is the key security detail. OpenClaw is not making CLI backends pretend they can enforce restricted tool policy. It is only preventing ordinary job edits from corrupting the meaning of the existing default policy.</p><h2>Why It Matters</h2><p>Scheduled jobs are often edited by agents themselves: prompt tweaks, timing adjustments, delivery target changes, or small workflow refinements. If those edits can break future runs without touching the tool policy, cron becomes fragile in exactly the place it should be dependable.</p><p>This fix restores the expected contract. Editing a scheduled job's message or prompt should not change whether the runtime considers its tool list default or restricted.</p><p>It also protects a useful operator workflow: CLI-backed scheduled jobs can continue using default tool access while still rejecting explicit restricted policies that the backend cannot enforce.</p><h2>Validation</h2><p>The PR reports a fail-confirmed regression in <code>service.jobs.test.ts</code>: before the fix, a patch with an unchanged list, changed message, and missing marker failed. After the fix, the combined jobs and run-executor message-tool-policy suites passed 132 tests.</p><p>An executor-level test also asserts that the CLI run context no longer throws for the repaired default-marker case. Lint and whitespace checks were clean, and the PR landed after manual orchestrator review.</p><h2>Bottom Line</h2><p>OpenClaw cron edits are now less brittle. Agents and operators can adjust scheduled jobs without accidentally turning a default tool inventory into an unenforceable explicit restriction that stops future CLI backend runs.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-cron-toolsallow-marker.png\" alt=\"OpenClaw Cron Edits Stop Breaking CLI Runs\" /></p>",
      "date_published": "2026-07-05T08:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Cron",
        "Edits",
        "Stop",
        "Breaking",
        "Runs"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-cron-toolsallow-marker.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-5-cron-toolsallow-marker.png",
          "mime_type": "image/png",
          "title": "OpenClaw Cron Edits Stop Breaking CLI Runs cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-extended-stable-updates/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-extended-stable-updates/",
      "title": "OpenClaw Adds Extended-Stable Updates",
      "summary": "OpenClaw now has an extended-stable package update channel for operators who need the trailing supported-month npm release.",
      "content_text": "OpenClaw merged [PR #99811, \"feat(update): support extended-stable package updates\"](https://github.com/openclaw/openclaw/pull/99811), adding a new update channel for package-install users who want the trailing supported-month release line.\n\nUntil now, OpenClaw had no canonical CLI contract for that lane. The existing `stable` channel already maps to npm `latest`, so operators who needed a slower package track had to work around the updater rather than express that choice directly.\n\nThis PR introduces `extended-stable` as a package-only channel across configuration, CLI update commands, status reporting, Gateway handoff, and Package Acceptance.\n\n## What Extended Stable Means\n\nThe new channel is designed for npm package installs, not Git checkouts. Package users can run:\n\n```bash\nopenclaw update --channel extended-stable\n```\n\nOnce selected, OpenClaw can persist that channel choice, allow bare foreground updates afterward, and show availability through `openclaw update status`.\n\nThe PR says the existing `stable`, `beta`, and `dev` defaults and mappings are unchanged. It also says startup and background auto-update are skipped for `extended-stable`, keeping the new lane focused on explicit foreground updates.\n\n## Fail-Closed Resolution\n\nThe most important design detail is failure behavior. Foreground updates resolve the public npm selector, verify the selected exact package, reuse existing downgrade and post-core commit boundaries, and reject Git checkouts and tag overrides before mutating anything.\n\nIf public npm metadata is missing or inconsistent, the updater does not fall back to another release line. Git users receive a structured non-mutating error.\n\nThat matters because update channels are trust boundaries as much as convenience flags. A channel named `extended-stable` only helps if it resolves exactly to that lane or refuses to act.\n\n## Current Publication Caveat\n\nThe PR is explicit that the current public-registry prerequisite check returned a 404 for `openclaw@extended-stable` during validation. Positive live-package proof is blocked until the related publication workflow in [PR #99352](https://github.com/openclaw/openclaw/pull/99352) ships the dist-tag.\n\nThat means this merge adds the updater machinery and fail-closed behavior first. The public npm lane still needs the matching publication side before operators can rely on a live `extended-stable` dist-tag in production.\n\n## Validation\n\nThe PR reports the full CLI update suite passing with 174 tests. It also lists a focused policy matrix covering extended-stable transaction cases, exact-resolution and tag-guard cases, startup/status/channel regressions, Gateway handoff behavior, and Package Acceptance allowlisting for `openclaw@extended-stable`.\n\nGenerated config schema, help baselines, base schema generation, formatting, MDX, markdownlint, docs map, and 5,550 internal links also passed.\n\nThe live fail-closed proof is the key result. Running the real CLI entrypoint against the current public registry returned a structured `selector_missing` error, a nonzero exit, an empty mutation-step list, and unchanged absent config. A loopback Verdaccio proof then validated successful install and foreground update behavior with a local `extended-stable` dist-tag.\n\n## Bottom Line\n\nOpenClaw is preparing a slower package update lane without changing what `stable` means today. The merge gives operators a named `extended-stable` channel, plus the fail-closed plumbing needed to keep that channel honest once the public dist-tag is published.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99811\">PR #99811, \"feat(update): support extended-stable package updates\"</a>, adding a new update channel for package-install users who want the trailing supported-month release line.</p><p>Until now, OpenClaw had no canonical CLI contract for that lane. The existing <code>stable</code> channel already maps to npm <code>latest</code>, so operators who needed a slower package track had to work around the updater rather than express that choice directly.</p><p>This PR introduces <code>extended-stable</code> as a package-only channel across configuration, CLI update commands, status reporting, Gateway handoff, and Package Acceptance.</p><h2>What Extended Stable Means</h2><p>The new channel is designed for npm package installs, not Git checkouts. Package users can run:</p><p>``<code>bash<br />openclaw update --channel extended-stable<br /></code>`<code></p><p>Once selected, OpenClaw can persist that channel choice, allow bare foreground updates afterward, and show availability through </code>openclaw update status<code>.</p><p>The PR says the existing </code>stable<code>, </code>beta<code>, and </code>dev<code> defaults and mappings are unchanged. It also says startup and background auto-update are skipped for </code>extended-stable<code>, keeping the new lane focused on explicit foreground updates.</p><h2>Fail-Closed Resolution</h2><p>The most important design detail is failure behavior. Foreground updates resolve the public npm selector, verify the selected exact package, reuse existing downgrade and post-core commit boundaries, and reject Git checkouts and tag overrides before mutating anything.</p><p>If public npm metadata is missing or inconsistent, the updater does not fall back to another release line. Git users receive a structured non-mutating error.</p><p>That matters because update channels are trust boundaries as much as convenience flags. A channel named </code>extended-stable<code> only helps if it resolves exactly to that lane or refuses to act.</p><h2>Current Publication Caveat</h2><p>The PR is explicit that the current public-registry prerequisite check returned a 404 for </code>openclaw@extended-stable<code> during validation. Positive live-package proof is blocked until the related publication workflow in <a href=\"https://github.com/openclaw/openclaw/pull/99352\">PR #99352</a> ships the dist-tag.</p><p>That means this merge adds the updater machinery and fail-closed behavior first. The public npm lane still needs the matching publication side before operators can rely on a live </code>extended-stable<code> dist-tag in production.</p><h2>Validation</h2><p>The PR reports the full CLI update suite passing with 174 tests. It also lists a focused policy matrix covering extended-stable transaction cases, exact-resolution and tag-guard cases, startup/status/channel regressions, Gateway handoff behavior, and Package Acceptance allowlisting for </code>openclaw@extended-stable<code>.</p><p>Generated config schema, help baselines, base schema generation, formatting, MDX, markdownlint, docs map, and 5,550 internal links also passed.</p><p>The live fail-closed proof is the key result. Running the real CLI entrypoint against the current public registry returned a structured </code>selector_missing<code> error, a nonzero exit, an empty mutation-step list, and unchanged absent config. A loopback Verdaccio proof then validated successful install and foreground update behavior with a local </code>extended-stable<code> dist-tag.</p><h2>Bottom Line</h2><p>OpenClaw is preparing a slower package update lane without changing what </code>stable<code> means today. The merge gives operators a named </code>extended-stable` channel, plus the fail-closed plumbing needed to keep that channel honest once the public dist-tag is published.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-extended-stable-updates.png\" alt=\"OpenClaw Adds Extended-Stable Updates\" /></p>",
      "date_published": "2026-07-04T23:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "Adds",
        "Extended",
        "Stable",
        "Updates"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-extended-stable-updates.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-extended-stable-updates.png",
          "mime_type": "image/png",
          "title": "OpenClaw Adds Extended-Stable Updates cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-codex-runtime-pin-guard/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-codex-runtime-pin-guard/",
      "title": "OpenClaw Blocks Stale Codex Runtime Pins",
      "summary": "OpenClaw release checks now fail closed when the Codex plugin would publish with an older embedded Codex runtime.",
      "content_text": "OpenClaw merged [PR #100015, \"fix(release): block stale Codex runtime pins\"](https://github.com/openclaw/openclaw/pull/100015), a P1 release-safety change for the bundled Codex plugin.\n\nThe issue was not whether an installed host could find Codex. It was more subtle: the stable `@openclaw/codex` package could be published with an older embedded `@openai/codex` runtime even after a newer stable Codex release was already available.\n\nThat creates a false-green state. The OpenClaw updater can correctly decide that the plugin package is current, while the route launched by that package still uses a stale executable dependency.\n\n## The Concrete Failure\n\nThe PR gives a specific example. On June 30, 2026, `@openclaw/codex@2026.6.11` was published with `@openai/codex@0.139.0`, even though `@openai/codex@0.142.4` had already been published on June 29, 2026.\n\nBefore this fix, the release pipeline checked internal package consistency, but it did not independently ask whether the selected executable dependency was current against npm's `latest` dist-tag.\n\nFor users, that distinction matters. A plugin can be internally consistent and still ship an older runtime than operators expect.\n\n## What Changed\n\nThe fix moves the invariant to the release-owner boundary. `@openclaw/codex` now opts its `@openai/codex` executable dependency into a strict freshness contract through plugin metadata.\n\nThe generic plugin release checker then validates configured executable dependencies as exact runtime dependencies and resolves npm's `latest` dist-tag independently during release checks and release-plan collection.\n\nIf the pinned dependency is stale, or if the freshness check cannot be verified, release planning fails closed instead of accepting the artifact.\n\nThe PR also updates the Codex runtime pin from `0.142.4` to `0.142.5`, refreshes generated lock data, and regenerates the harness model snapshot from the actual `0.142.5` app-server.\n\n## What It Does Not Do\n\nThis is intentionally not a broad runtime inspection system. The PR says it does not add generic-core Codex version policy, inspect arbitrary selected binaries at runtime, or change plugin update-channel behavior.\n\nThat restraint is important. Runtime inspection can produce false positives for supported alternate routes, and it cannot stop a stale artifact from being published in the first place. The fix targets the release validation point where the bad package can be blocked before users receive it.\n\n## Validation\n\nThe PR reports five focused test files passing across 76 Vitest tests, including plugin npm release checks, ClawHub release checks, wrapper script tests, Codex manifest tests, and app-server model snapshot tests.\n\nIt also reports a successful Codex shrinkwrap check, a live npm-backed plugin release check for `@openclaw/codex`, and an AWS Linux Crabbox changed-lane run covering dependency guards, full typecheck, lint, and import-cycle checks.\n\nA real `codex app-server` `model/list` probe reported server version `0.142.5`, which was used to update the public model snapshot. No npm publish was performed as part of the PR validation, and already-installed `@openclaw/codex@2026.6.11` packages remain unchanged until a new plugin release is published and installed.\n\n## Bottom Line\n\nOpenClaw's Codex plugin release path now has a sharper guardrail: a stale embedded Codex runtime should block publication instead of reaching operators as a seemingly current package.\n\nFor teams relying on Codex through OpenClaw, that means fewer hidden version gaps between the plugin they updated and the runtime it actually launches.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100015\">PR #100015, \"fix(release): block stale Codex runtime pins\"</a>, a P1 release-safety change for the bundled Codex plugin.</p><p>The issue was not whether an installed host could find Codex. It was more subtle: the stable <code>@openclaw/codex</code> package could be published with an older embedded <code>@openai/codex</code> runtime even after a newer stable Codex release was already available.</p><p>That creates a false-green state. The OpenClaw updater can correctly decide that the plugin package is current, while the route launched by that package still uses a stale executable dependency.</p><h2>The Concrete Failure</h2><p>The PR gives a specific example. On June 30, 2026, <code>@openclaw/codex@2026.6.11</code> was published with <code>@openai/codex@0.139.0</code>, even though <code>@openai/codex@0.142.4</code> had already been published on June 29, 2026.</p><p>Before this fix, the release pipeline checked internal package consistency, but it did not independently ask whether the selected executable dependency was current against npm's <code>latest</code> dist-tag.</p><p>For users, that distinction matters. A plugin can be internally consistent and still ship an older runtime than operators expect.</p><h2>What Changed</h2><p>The fix moves the invariant to the release-owner boundary. <code>@openclaw/codex</code> now opts its <code>@openai/codex</code> executable dependency into a strict freshness contract through plugin metadata.</p><p>The generic plugin release checker then validates configured executable dependencies as exact runtime dependencies and resolves npm's <code>latest</code> dist-tag independently during release checks and release-plan collection.</p><p>If the pinned dependency is stale, or if the freshness check cannot be verified, release planning fails closed instead of accepting the artifact.</p><p>The PR also updates the Codex runtime pin from <code>0.142.4</code> to <code>0.142.5</code>, refreshes generated lock data, and regenerates the harness model snapshot from the actual <code>0.142.5</code> app-server.</p><h2>What It Does Not Do</h2><p>This is intentionally not a broad runtime inspection system. The PR says it does not add generic-core Codex version policy, inspect arbitrary selected binaries at runtime, or change plugin update-channel behavior.</p><p>That restraint is important. Runtime inspection can produce false positives for supported alternate routes, and it cannot stop a stale artifact from being published in the first place. The fix targets the release validation point where the bad package can be blocked before users receive it.</p><h2>Validation</h2><p>The PR reports five focused test files passing across 76 Vitest tests, including plugin npm release checks, ClawHub release checks, wrapper script tests, Codex manifest tests, and app-server model snapshot tests.</p><p>It also reports a successful Codex shrinkwrap check, a live npm-backed plugin release check for <code>@openclaw/codex</code>, and an AWS Linux Crabbox changed-lane run covering dependency guards, full typecheck, lint, and import-cycle checks.</p><p>A real <code>codex app-server</code> <code>model/list</code> probe reported server version <code>0.142.5</code>, which was used to update the public model snapshot. No npm publish was performed as part of the PR validation, and already-installed <code>@openclaw/codex@2026.6.11</code> packages remain unchanged until a new plugin release is published and installed.</p><h2>Bottom Line</h2><p>OpenClaw's Codex plugin release path now has a sharper guardrail: a stale embedded Codex runtime should block publication instead of reaching operators as a seemingly current package.</p><p>For teams relying on Codex through OpenClaw, that means fewer hidden version gaps between the plugin they updated and the runtime it actually launches.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-codex-runtime-pin-guard.png\" alt=\"OpenClaw Blocks Stale Codex Runtime Pins\" /></p>",
      "date_published": "2026-07-04T23:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "Blocks",
        "Stale",
        "Codex",
        "Runtime",
        "Pins"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-codex-runtime-pin-guard.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-codex-runtime-pin-guard.png",
          "mime_type": "image/png",
          "title": "OpenClaw Blocks Stale Codex Runtime Pins cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-terminal-reattach/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-terminal-reattach/",
      "title": "OpenClaw Terminals Now Survive Reconnects",
      "summary": "OpenClaw's Control UI terminal can now detach, reattach, and replay recent output after reloads, sleep, or network drops.",
      "content_text": "OpenClaw merged [PR #100089, \"feat(gateway): terminal detach/reattach with output replay, terminal.list, terminal.text\"](https://github.com/openclaw/openclaw/pull/100089) minutes before the July 4th nightly cutoff, adding a long-requested reliability layer to the Control UI terminal.\n\nThe problem was simple and painful: terminal sessions were tied directly to the Gateway WebSocket connection. If an operator closed a laptop, refreshed the browser, or hit a transient network drop, the PTY tree was killed immediately. Any command running inside that terminal went with it.\n\nThis PR changes that model. Terminal sessions can now outlive the viewer connection, reattach later, and replay recent output so operators can keep their place.\n\n## What Changed\n\nThe new terminal behavior is built around a bounded output ring and an explicit detach lifecycle. Each terminal session keeps a 256 KiB buffer of recent raw output. When the Control UI reconnects, it can replay that buffer before streaming new output.\n\nThe Gateway now exposes three additive terminal methods:\n\n- `terminal.attach {sessionId}` rebinds a live or detached terminal session to the current admin connection and returns its buffered output.\n- `terminal.list` returns attachable sessions, including the shell, working directory, agent id, attachment state, and creation time.\n- `terminal.text {sessionId}` returns the buffered terminal output as plain text without attaching.\n\nThat last method is especially useful for agent and tool workflows. It gives an LLM-readable view of recent terminal output without taking over the operator's session.\n\n## Safer Detach Semantics\n\nDisconnects now park terminal sessions instead of killing them immediately. Detached sessions are reaped after `gateway.terminal.detachedSessionTimeoutSeconds`, which defaults to 300 seconds. Operators who prefer the old fail-closed behavior can set that value to `0`.\n\nThe PR also caps detached sessions at eight, evicting the oldest when needed, and still hard-kills everything on Gateway shutdown. That keeps the feature useful for ordinary reconnects without turning terminals into unbounded background processes.\n\nThe Control UI stores live terminal session ids per browser tab using `sessionStorage`. That is deliberate: reattach is a take-over operation, so using shared origin-wide storage would let multiple windows clobber each other's terminal session ids.\n\n## Why It Matters\n\nThis is a quality-of-life change, but it touches a serious operator workflow. OpenClaw's terminal is used for long-running installs, diagnostics, tests, and maintenance commands. Losing that shell because a laptop slept or a browser tab refreshed is more than annoying; it can leave users unsure whether a command is still running, partially applied, or gone.\n\nThe new model is closer to a lightweight tmux-style recovery path. It does not promise full terminal persistence across Gateway restarts, multi-viewer sharing, or a true server-side VT snapshot. The PR explicitly leaves those as follow-ups. But it does cover the common reconnect cases that trip up daily Control UI use.\n\n## Validation\n\nThe PR reports focused unit coverage for output ring bounds, detach and reaper timing, attach rebinding, buffer replay, text rendering, live owner take-over notifications, list ordering, detached-session cap eviction, shutdown cleanup, and handler kill-switch gating.\n\nIt also includes a live end-to-end test against a real dist Gateway. The test started a looping terminal command, reloaded the page, confirmed the same session id reattached, saw earlier ticks replay from the buffer, and then verified new terminal input still worked after reload.\n\nTypecheck and lint lanes were reported clean, and a review concern about teardown close RPCs killing reattachable sessions was rejected with live proof and a documented invariant.\n\n## Bottom Line\n\nOpenClaw terminals are becoming resilient enough for real operator work. Reloads, laptop sleep, and short network drops no longer have to mean losing the shell, the output, and the command that was still running.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/100089\">PR #100089, \"feat(gateway): terminal detach/reattach with output replay, terminal.list, terminal.text\"</a> minutes before the July 4th nightly cutoff, adding a long-requested reliability layer to the Control UI terminal.</p><p>The problem was simple and painful: terminal sessions were tied directly to the Gateway WebSocket connection. If an operator closed a laptop, refreshed the browser, or hit a transient network drop, the PTY tree was killed immediately. Any command running inside that terminal went with it.</p><p>This PR changes that model. Terminal sessions can now outlive the viewer connection, reattach later, and replay recent output so operators can keep their place.</p><h2>What Changed</h2><p>The new terminal behavior is built around a bounded output ring and an explicit detach lifecycle. Each terminal session keeps a 256 KiB buffer of recent raw output. When the Control UI reconnects, it can replay that buffer before streaming new output.</p><p>The Gateway now exposes three additive terminal methods:</p><ul><li><code>terminal.attach {sessionId}</code> rebinds a live or detached terminal session to the current admin connection and returns its buffered output.</li><li><code>terminal.list</code> returns attachable sessions, including the shell, working directory, agent id, attachment state, and creation time.</li><li><code>terminal.text {sessionId}</code> returns the buffered terminal output as plain text without attaching.</li></ul><p>That last method is especially useful for agent and tool workflows. It gives an LLM-readable view of recent terminal output without taking over the operator's session.</p><h2>Safer Detach Semantics</h2><p>Disconnects now park terminal sessions instead of killing them immediately. Detached sessions are reaped after <code>gateway.terminal.detachedSessionTimeoutSeconds</code>, which defaults to 300 seconds. Operators who prefer the old fail-closed behavior can set that value to <code>0</code>.</p><p>The PR also caps detached sessions at eight, evicting the oldest when needed, and still hard-kills everything on Gateway shutdown. That keeps the feature useful for ordinary reconnects without turning terminals into unbounded background processes.</p><p>The Control UI stores live terminal session ids per browser tab using <code>sessionStorage</code>. That is deliberate: reattach is a take-over operation, so using shared origin-wide storage would let multiple windows clobber each other's terminal session ids.</p><h2>Why It Matters</h2><p>This is a quality-of-life change, but it touches a serious operator workflow. OpenClaw's terminal is used for long-running installs, diagnostics, tests, and maintenance commands. Losing that shell because a laptop slept or a browser tab refreshed is more than annoying; it can leave users unsure whether a command is still running, partially applied, or gone.</p><p>The new model is closer to a lightweight tmux-style recovery path. It does not promise full terminal persistence across Gateway restarts, multi-viewer sharing, or a true server-side VT snapshot. The PR explicitly leaves those as follow-ups. But it does cover the common reconnect cases that trip up daily Control UI use.</p><h2>Validation</h2><p>The PR reports focused unit coverage for output ring bounds, detach and reaper timing, attach rebinding, buffer replay, text rendering, live owner take-over notifications, list ordering, detached-session cap eviction, shutdown cleanup, and handler kill-switch gating.</p><p>It also includes a live end-to-end test against a real dist Gateway. The test started a looping terminal command, reloaded the page, confirmed the same session id reattached, saw earlier ticks replay from the buffer, and then verified new terminal input still worked after reload.</p><p>Typecheck and lint lanes were reported clean, and a review concern about teardown close RPCs killing reattachable sessions was rejected with live proof and a documented invariant.</p><h2>Bottom Line</h2><p>OpenClaw terminals are becoming resilient enough for real operator work. Reloads, laptop sleep, and short network drops no longer have to mean losing the shell, the output, and the command that was still running.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-terminal-reattach.png\" alt=\"OpenClaw Terminals Now Survive Reconnects\" /></p>",
      "date_published": "2026-07-04T23:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Terminals",
        "Survive",
        "Reconnects"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-terminal-reattach.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-terminal-reattach.png",
          "mime_type": "image/png",
          "title": "OpenClaw Terminals Now Survive Reconnects cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-reasoning-slider/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-reasoning-slider/",
      "title": "OpenClaw Control UI Adds a Reasoning Slider",
      "summary": "OpenClaw's Control UI now replaces a crowded reasoning list with a Faster-to-Smarter slider and quieter composer controls.",
      "content_text": "OpenClaw merged [PR #99838, \"feat: declutter the Control UI shell\"](https://github.com/openclaw/openclaw/pull/99838) just before the July 4th morning scan, continuing the Control UI cleanup that started with the session-first sidebar work.\n\nThis pass focuses on the chat composer and model picker. The PR says the chat surface carried chrome that competed with the content: bordered model and usage controls inside an already framed composer, a seven-item reasoning text-button list, and a persistent boxed version pill in the sidebar.\n\nThe goal is not a new navigation model. It is a quieter shell around the conversation.\n\n## What Changed\n\nComposer controls now become quieter text controls. The model picker trigger and provider-usage pill lose their filled, bordered treatment at rest, then get a soft hover or open state. The visible trigger shows just the model name unless a reasoning override is active, while accessibility text keeps the full model and level pair.\n\nThe bigger change is reasoning selection. Instead of a text-button list, OpenClaw now shows a native range input that runs from Faster to Smarter across the ordered reasoning levels the Gateway offers.\n\nThe slider includes stop dots, a filled track segment, a marker for the inherited default, a live value label, and a reset action for returning to the default. The PR says selection commits on release, not on every drag tick.\n\nThere are also edge-case fixes. A model with a single reasoning level renders a selectable toggle instead of a useless slider, and models without reasoning levels no longer show a dead Default-only control.\n\n## Sidebar Metadata Gets Quieter\n\nThe persistent sidebar version pill is replaced by a slim connection status line with a connection dot and Online or Offline state. The Gateway version is still visible in Settings, where the Quick Settings footer already reports the connected assistant and version.\n\nThat moves version metadata out of the primary workspace while keeping it one click away when it is actually needed.\n\n## Why It Matters\n\nReasoning effort is becoming a normal part of agent operation. If the control is buried in a long list, users have to parse the labels every time. A Faster-to-Smarter slider makes the tradeoff more legible: speed on one side, deeper reasoning on the other.\n\nThe quieter composer also helps the chat surface feel less crowded. A model picker, quota signal, reasoning control, connection status, and version metadata are all useful, but they do not need equal visual weight during every conversation.\n\n## Validation\n\nThe PR includes before-and-after captures from the mock-Gateway E2E harness. Its validation reports 258 focused tests passing across chat views, model selection state, navigation, app rendering helpers, and responsive chat behavior.\n\nNew coverage checks that the slider drives `sessions.patch` with the selected level, that singleton level lists remain selectable, that no-reasoning models do not render a dead control, and that the sidebar no longer shows version text.\n\nThe PR also reports clean `tsgo`, `oxfmt --check`, `oxlint`, and Control UI i18n checks. One automated review finding about singleton levels was accepted and fixed with a regression test.\n\n## Bottom Line\n\nOpenClaw's Control UI is getting calmer without hiding the controls operators need. The reasoning slider makes model effort easier to adjust, and the composer/sidebar cleanup reduces visual noise around active sessions.\n\nFor daily users, this should make the web UI feel more like an agent workspace and less like a settings panel wrapped around chat.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99838\">PR #99838, \"feat: declutter the Control UI shell\"</a> just before the July 4th morning scan, continuing the Control UI cleanup that started with the session-first sidebar work.</p><p>This pass focuses on the chat composer and model picker. The PR says the chat surface carried chrome that competed with the content: bordered model and usage controls inside an already framed composer, a seven-item reasoning text-button list, and a persistent boxed version pill in the sidebar.</p><p>The goal is not a new navigation model. It is a quieter shell around the conversation.</p><h2>What Changed</h2><p>Composer controls now become quieter text controls. The model picker trigger and provider-usage pill lose their filled, bordered treatment at rest, then get a soft hover or open state. The visible trigger shows just the model name unless a reasoning override is active, while accessibility text keeps the full model and level pair.</p><p>The bigger change is reasoning selection. Instead of a text-button list, OpenClaw now shows a native range input that runs from Faster to Smarter across the ordered reasoning levels the Gateway offers.</p><p>The slider includes stop dots, a filled track segment, a marker for the inherited default, a live value label, and a reset action for returning to the default. The PR says selection commits on release, not on every drag tick.</p><p>There are also edge-case fixes. A model with a single reasoning level renders a selectable toggle instead of a useless slider, and models without reasoning levels no longer show a dead Default-only control.</p><h2>Sidebar Metadata Gets Quieter</h2><p>The persistent sidebar version pill is replaced by a slim connection status line with a connection dot and Online or Offline state. The Gateway version is still visible in Settings, where the Quick Settings footer already reports the connected assistant and version.</p><p>That moves version metadata out of the primary workspace while keeping it one click away when it is actually needed.</p><h2>Why It Matters</h2><p>Reasoning effort is becoming a normal part of agent operation. If the control is buried in a long list, users have to parse the labels every time. A Faster-to-Smarter slider makes the tradeoff more legible: speed on one side, deeper reasoning on the other.</p><p>The quieter composer also helps the chat surface feel less crowded. A model picker, quota signal, reasoning control, connection status, and version metadata are all useful, but they do not need equal visual weight during every conversation.</p><h2>Validation</h2><p>The PR includes before-and-after captures from the mock-Gateway E2E harness. Its validation reports 258 focused tests passing across chat views, model selection state, navigation, app rendering helpers, and responsive chat behavior.</p><p>New coverage checks that the slider drives <code>sessions.patch</code> with the selected level, that singleton level lists remain selectable, that no-reasoning models do not render a dead control, and that the sidebar no longer shows version text.</p><p>The PR also reports clean <code>tsgo</code>, <code>oxfmt --check</code>, <code>oxlint</code>, and Control UI i18n checks. One automated review finding about singleton levels was accepted and fixed with a regression test.</p><h2>Bottom Line</h2><p>OpenClaw's Control UI is getting calmer without hiding the controls operators need. The reasoning slider makes model effort easier to adjust, and the composer/sidebar cleanup reduces visual noise around active sessions.</p><p>For daily users, this should make the web UI feel more like an agent workspace and less like a settings panel wrapped around chat.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-reasoning-slider.png\" alt=\"OpenClaw Control UI Adds a Reasoning Slider\" /></p>",
      "date_published": "2026-07-04T08:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Control",
        "Adds",
        "Reasoning",
        "Slider"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-reasoning-slider.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-reasoning-slider.png",
          "mime_type": "image/png",
          "title": "OpenClaw Control UI Adds a Reasoning Slider cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-node-23-runtime-guard/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-node-23-runtime-guard/",
      "title": "OpenClaw Blocks Incompatible Node 23 Runtimes",
      "summary": "OpenClaw now rejects Node 23.0 through 23.10 before startup, preventing SQLite runtime failures from reaching users during setup.",
      "content_text": "OpenClaw merged [PR #99832, \"fix: reject incompatible Node 23 runtimes\"](https://github.com/openclaw/openclaw/pull/99832) on July 4th, tightening the runtime contract around a specific Node.js compatibility gap.\n\nThe PR is labeled P0 and compatibility-risk because the failure mode could hit users before OpenClaw reached a useful state. OpenClaw could install successfully on Node 23.0 through 23.10, then fail at startup or during state migration because those releases do not expose the required `StatementSync.columns()` API.\n\nThat is the kind of setup bug that feels especially frustrating: the installer appears to accept the environment, but the product fails later in a lower-level SQLite-backed path.\n\n## What Changed\n\nThe supported runtime contract is now narrower and clearer. OpenClaw accepts Node 22.19+, Node 23.11+, or newer major versions, and rejects Node 23.0 through 23.10 consistently across the setup and launch path.\n\nThe PR applies the boundary in several places:\n\n- package metadata\n- the launcher\n- runtime guards\n- daemon diagnostics\n- the macOS runtime locator\n- shell, PowerShell, and CLI-only installers\n\nThe CLI-only installer also verifies the required `node:sqlite` statement API before accepting an existing runtime. That matters because a version number check alone is less useful than proving the API OpenClaw actually needs is available.\n\n## Why It Matters\n\nOpenClaw has been adding more native app, Gateway, and local-first workflows. Those paths depend on setup reliability. If a user has an incompatible but superficially modern Node 23 runtime, OpenClaw needs to stop early with an actionable message instead of reaching a runtime crash.\n\nPR #99832 turns that into a direct compatibility guard. Node 23.7, for example, is now rejected before startup with a supported-range diagnostic. Node 22.19, Node 23.11, and Node 24 proceed successfully in the reported launcher matrix.\n\nThat makes the installation contract easier to explain and easier to debug.\n\n## Validation\n\nThe PR reports a focused Vitest matrix with seven files passing, nine tests passing, and 197 skipped. The author also ran a real launcher matrix with Node 22.19, 23.7, 23.11, and 24.\n\nThe important behavioral proof is the boundary itself: Node 23.7 exits with the supported-range diagnostic, while Node 22.19, 23.11, and 24 start successfully.\n\nAdditional validation included `bash -n` checks for the install scripts, byte-identical installer source files against the companion `openclaw.ai` branch, AWS Crabbox Linux changed checks and build proof, and a final automated review with no accepted actionable findings.\n\nThe only noted local gap is the macOS Swift unit suite, which could not run locally because the package requires Swift 6.2 while the installed toolchain was Swift 6.0. The PR says RuntimeLocator boundary tests are included for CI.\n\n## Bottom Line\n\nThis is not a flashy feature, but it is important release engineering. OpenClaw now rejects the broken Node 23 interval before users reach a SQLite-backed failure path.\n\nFor operators and Mac app users, that should turn a confusing startup crash into a clear runtime requirement.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99832\">PR #99832, \"fix: reject incompatible Node 23 runtimes\"</a> on July 4th, tightening the runtime contract around a specific Node.js compatibility gap.</p><p>The PR is labeled P0 and compatibility-risk because the failure mode could hit users before OpenClaw reached a useful state. OpenClaw could install successfully on Node 23.0 through 23.10, then fail at startup or during state migration because those releases do not expose the required <code>StatementSync.columns()</code> API.</p><p>That is the kind of setup bug that feels especially frustrating: the installer appears to accept the environment, but the product fails later in a lower-level SQLite-backed path.</p><h2>What Changed</h2><p>The supported runtime contract is now narrower and clearer. OpenClaw accepts Node 22.19+, Node 23.11+, or newer major versions, and rejects Node 23.0 through 23.10 consistently across the setup and launch path.</p><p>The PR applies the boundary in several places:</p><ul><li>package metadata</li><li>the launcher</li><li>runtime guards</li><li>daemon diagnostics</li><li>the macOS runtime locator</li><li>shell, PowerShell, and CLI-only installers</li></ul><p>The CLI-only installer also verifies the required <code>node:sqlite</code> statement API before accepting an existing runtime. That matters because a version number check alone is less useful than proving the API OpenClaw actually needs is available.</p><h2>Why It Matters</h2><p>OpenClaw has been adding more native app, Gateway, and local-first workflows. Those paths depend on setup reliability. If a user has an incompatible but superficially modern Node 23 runtime, OpenClaw needs to stop early with an actionable message instead of reaching a runtime crash.</p><p>PR #99832 turns that into a direct compatibility guard. Node 23.7, for example, is now rejected before startup with a supported-range diagnostic. Node 22.19, Node 23.11, and Node 24 proceed successfully in the reported launcher matrix.</p><p>That makes the installation contract easier to explain and easier to debug.</p><h2>Validation</h2><p>The PR reports a focused Vitest matrix with seven files passing, nine tests passing, and 197 skipped. The author also ran a real launcher matrix with Node 22.19, 23.7, 23.11, and 24.</p><p>The important behavioral proof is the boundary itself: Node 23.7 exits with the supported-range diagnostic, while Node 22.19, 23.11, and 24 start successfully.</p><p>Additional validation included <code>bash -n</code> checks for the install scripts, byte-identical installer source files against the companion <code>openclaw.ai</code> branch, AWS Crabbox Linux changed checks and build proof, and a final automated review with no accepted actionable findings.</p><p>The only noted local gap is the macOS Swift unit suite, which could not run locally because the package requires Swift 6.2 while the installed toolchain was Swift 6.0. The PR says RuntimeLocator boundary tests are included for CI.</p><h2>Bottom Line</h2><p>This is not a flashy feature, but it is important release engineering. OpenClaw now rejects the broken Node 23 interval before users reach a SQLite-backed failure path.</p><p>For operators and Mac app users, that should turn a confusing startup crash into a clear runtime requirement.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-node-23-runtime-guard.png\" alt=\"OpenClaw Blocks Incompatible Node 23 Runtimes\" /></p>",
      "date_published": "2026-07-04T08:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Guides",
        "Blocks",
        "Incompatible",
        "Node",
        "Runtimes"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-node-23-runtime-guard.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-node-23-runtime-guard.png",
          "mime_type": "image/png",
          "title": "OpenClaw Blocks Incompatible Node 23 Runtimes cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-4-mac-gateway-setup/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-4-mac-gateway-setup/",
      "title": "OpenClaw Mac Setup Now Starts Gateway for You",
      "summary": "OpenClaw's Mac app can now install the CLI, start the local Gateway, and approve its own node so fresh users reach a working agent faster.",
      "content_text": "OpenClaw merged [PR #99767, \"feat(macos): install and run the local Gateway automatically\"](https://github.com/openclaw/openclaw/pull/99767) early on July 4th, bringing the Mac app closer to a true first-run installer.\n\nThe problem was straightforward: people could download OpenClaw for Mac and still fail to complete setup from the app alone if the CLI, Node.js, and local Gateway were not already present. That is a big onboarding gap for a desktop app whose best experience should start inside the app, not in a terminal checklist.\n\nThe PR also fixes a smaller but important trust-flow annoyance. Fresh local installs could prompt for approval of the Mac app's own node, even though that node belongs to the local setup path the user just chose.\n\n## What Changed\n\nThe Mac app now bundles the canonical CLI installer, defaults onboarding to **This Mac**, installs and starts the local Gateway, and waits until the Gateway is ready. A new user should be able to drag OpenClaw into Applications, open it, choose the recommended local setup, and reach a working agent.\n\nThe local node pairing flow is also tighter. Fresh installs use a dedicated node identity, and the app silently approves only the exact persisted node identity in local mode. Remote nodes and mismatched identities still require explicit approval.\n\nThat distinction matters. The change removes an unnecessary prompt for the app's own local node while preserving the approval boundary for anything that is not the expected local identity.\n\n## Why It Matters\n\nMac onboarding is often the first impression for users who want OpenClaw as a personal agent, not just as a developer project. If the first-run path depends on preinstalled runtime pieces, the desktop app feels more like a wrapper than a complete product.\n\nPR #99767 moves more of that responsibility into the app:\n\n- CLI installation is part of the onboarding flow.\n- The local Gateway starts automatically.\n- The app waits for Gateway readiness before moving on.\n- The local Mac node can be approved without a redundant pairing sheet.\n\nThat should reduce the number of users who stall before they ever reach a live conversation.\n\n## Validation\n\nThe PR says the flow was tested from a fresh Parallels macOS Tahoe 26.5 snapshot where OpenClaw, its state, the CLI, and Node.js were absent. The final signed and notarized universal DMG passed `hdiutil verify`, `stapler validate`, and Gatekeeper assessment.\n\nIn the clean setup proof, OpenClaw installed CLI/Gateway 2026.6.11, loaded the LaunchAgent, reached the loopback Gateway at `127.0.0.1:18789`, and completed onboarding. The app's own node reported approved, paired, and connected, with no node approval sheet shown during setup.\n\nThe PR also reports a live OpenAI-backed onboarding turn that returned the exact response `OPENCLAW_E2E_OK`, plus focused Swift, macOS onboarding, installer, package, and JavaScript build validation.\n\n## Bottom Line\n\nThis is a meaningful platform improvement for OpenClaw on macOS. The app can now carry more of the setup burden itself, while keeping remote and mismatched node approvals explicit.\n\nFor first-time Mac users, that makes OpenClaw feel less like a multi-step system install and more like a desktop app that knows how to bring its agent runtime online.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99767\">PR #99767, \"feat(macos): install and run the local Gateway automatically\"</a> early on July 4th, bringing the Mac app closer to a true first-run installer.</p><p>The problem was straightforward: people could download OpenClaw for Mac and still fail to complete setup from the app alone if the CLI, Node.js, and local Gateway were not already present. That is a big onboarding gap for a desktop app whose best experience should start inside the app, not in a terminal checklist.</p><p>The PR also fixes a smaller but important trust-flow annoyance. Fresh local installs could prompt for approval of the Mac app's own node, even though that node belongs to the local setup path the user just chose.</p><h2>What Changed</h2><p>The Mac app now bundles the canonical CLI installer, defaults onboarding to <strong>This Mac</strong>, installs and starts the local Gateway, and waits until the Gateway is ready. A new user should be able to drag OpenClaw into Applications, open it, choose the recommended local setup, and reach a working agent.</p><p>The local node pairing flow is also tighter. Fresh installs use a dedicated node identity, and the app silently approves only the exact persisted node identity in local mode. Remote nodes and mismatched identities still require explicit approval.</p><p>That distinction matters. The change removes an unnecessary prompt for the app's own local node while preserving the approval boundary for anything that is not the expected local identity.</p><h2>Why It Matters</h2><p>Mac onboarding is often the first impression for users who want OpenClaw as a personal agent, not just as a developer project. If the first-run path depends on preinstalled runtime pieces, the desktop app feels more like a wrapper than a complete product.</p><p>PR #99767 moves more of that responsibility into the app:</p><ul><li>CLI installation is part of the onboarding flow.</li><li>The local Gateway starts automatically.</li><li>The app waits for Gateway readiness before moving on.</li><li>The local Mac node can be approved without a redundant pairing sheet.</li></ul><p>That should reduce the number of users who stall before they ever reach a live conversation.</p><h2>Validation</h2><p>The PR says the flow was tested from a fresh Parallels macOS Tahoe 26.5 snapshot where OpenClaw, its state, the CLI, and Node.js were absent. The final signed and notarized universal DMG passed <code>hdiutil verify</code>, <code>stapler validate</code>, and Gatekeeper assessment.</p><p>In the clean setup proof, OpenClaw installed CLI/Gateway 2026.6.11, loaded the LaunchAgent, reached the loopback Gateway at <code>127.0.0.1:18789</code>, and completed onboarding. The app's own node reported approved, paired, and connected, with no node approval sheet shown during setup.</p><p>The PR also reports a live OpenAI-backed onboarding turn that returned the exact response <code>OPENCLAW_E2E_OK</code>, plus focused Swift, macOS onboarding, installer, package, and JavaScript build validation.</p><h2>Bottom Line</h2><p>This is a meaningful platform improvement for OpenClaw on macOS. The app can now carry more of the setup burden itself, while keeping remote and mismatched node approvals explicit.</p><p>For first-time Mac users, that makes OpenClaw feel less like a multi-step system install and more like a desktop app that knows how to bring its agent runtime online.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-mac-gateway-setup.png\" alt=\"OpenClaw Mac Setup Now Starts Gateway for You\" /></p>",
      "date_published": "2026-07-04T08:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Guides",
        "Setup",
        "Starts",
        "Gateway"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-mac-gateway-setup.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-4-mac-gateway-setup.png",
          "mime_type": "image/png",
          "title": "OpenClaw Mac Setup Now Starts Gateway for You cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-ios-permission-prompts-stop/",
      "url": "https://openclawchronicles.com/posts/openclaw-ios-permission-prompts-stop/",
      "title": "OpenClaw Stops iOS Node Permission Prompts",
      "summary": "OpenClaw now returns permission-required errors for iOS node calls instead of blocking gateway invokes with native prompts.",
      "content_text": "OpenClaw's iOS node gained an important execution-boundary fix today in [PR #99477](https://github.com/openclaw/openclaw/pull/99477). The change stops Calendar, Reminders, and Contacts node commands from opening native iOS permission prompts inside `node.invoke`.\n\nThat sounds small, but it closes a real agent-runtime trap. A gateway call is waiting for a node response. A native iOS permission sheet is waiting for foreground user interaction. If those two waits meet in the wrong place, the agent turn can hang until a timeout instead of getting a clear answer.\n\n## What Changed\n\nBefore this PR, iOS node commands could request permissions directly from service methods:\n\n- `calendar.events` and `calendar.add` could call EventKit request APIs.\n- `reminders.list` and `reminders.add` could call EventKit request APIs.\n- `contacts.search` and `contacts.add` could call Contacts access request APIs.\n\nThe PR applies the same contract that Photos already used: node services should not prompt during `node.invoke`. Instead, they should inspect current authorization state and return the existing service-specific permission error when access has not been granted.\n\nCalendar and Reminders now read EventKit authorization status through the existing read/write helpers. Contacts reads current Contacts authorization state and treats `.notDetermined` as unavailable. The actual permission prompts remain owned by the app's foreground Settings privacy surface, where a human is intentionally managing access.\n\n## Why It Matters\n\nMobile node calls are transport work. The Gateway sends a request, the node executes it, and the agent expects a structured response. Permission prompts are UI work. They need a person, a foreground app, and clear context about what is being allowed.\n\nMixing those two responsibilities makes failure confusing. An agent asking for contacts should be able to say \"permission required\" immediately. It should not stall because iOS is displaying a sheet the user may not see.\n\nThis fix is especially useful for OpenClaw setups where mobile nodes run as part of longer automations. If a calendar, reminder, or contact action lacks permission, the agent can now explain the missing permission path instead of burning the turn on a timeout.\n\n## Evidence From the PR\n\nThe PR added `NodeServicePermissionTests` for `.notDetermined` permission states across Calendar, Reminders, and Contacts. It also reports simulator testing on iOS 26.5 and two real setup-code pairings against an isolated local Gateway.\n\nThe before-and-after proof is direct. Before the fix, a real paired-gateway `contacts.search` invocation opened the native Contacts prompt from the node call, and leaving it unanswered caused gateway timeout behavior. After the fix, `contacts.search`, `calendar.events`, and `reminders.list` immediately returned their permission-required errors with no native alert.\n\nThe granted-permission path was also checked: once permissions were granted from the appropriate UI surface, those same node calls succeeded.\n\n## Bottom Line\n\nThis is a clean boundary fix. OpenClaw's iOS node services now keep `node.invoke` prompt-free for Calendar, Reminders, and Contacts. Permission requests stay in the app's settings UI, while agent calls get fast, structured permission errors when access is missing.\n\nFor anyone using iOS as an OpenClaw node, [PR #99477](https://github.com/openclaw/openclaw/pull/99477) should make permission failures much easier to understand and recover from.",
      "content_html": "<p>OpenClaw's iOS node gained an important execution-boundary fix today in <a href=\"https://github.com/openclaw/openclaw/pull/99477\">PR #99477</a>. The change stops Calendar, Reminders, and Contacts node commands from opening native iOS permission prompts inside <code>node.invoke</code>.</p><p>That sounds small, but it closes a real agent-runtime trap. A gateway call is waiting for a node response. A native iOS permission sheet is waiting for foreground user interaction. If those two waits meet in the wrong place, the agent turn can hang until a timeout instead of getting a clear answer.</p><h2>What Changed</h2><p>Before this PR, iOS node commands could request permissions directly from service methods:</p><ul><li><code>calendar.events</code> and <code>calendar.add</code> could call EventKit request APIs.</li><li><code>reminders.list</code> and <code>reminders.add</code> could call EventKit request APIs.</li><li><code>contacts.search</code> and <code>contacts.add</code> could call Contacts access request APIs.</li></ul><p>The PR applies the same contract that Photos already used: node services should not prompt during <code>node.invoke</code>. Instead, they should inspect current authorization state and return the existing service-specific permission error when access has not been granted.</p><p>Calendar and Reminders now read EventKit authorization status through the existing read/write helpers. Contacts reads current Contacts authorization state and treats <code>.notDetermined</code> as unavailable. The actual permission prompts remain owned by the app's foreground Settings privacy surface, where a human is intentionally managing access.</p><h2>Why It Matters</h2><p>Mobile node calls are transport work. The Gateway sends a request, the node executes it, and the agent expects a structured response. Permission prompts are UI work. They need a person, a foreground app, and clear context about what is being allowed.</p><p>Mixing those two responsibilities makes failure confusing. An agent asking for contacts should be able to say \"permission required\" immediately. It should not stall because iOS is displaying a sheet the user may not see.</p><p>This fix is especially useful for OpenClaw setups where mobile nodes run as part of longer automations. If a calendar, reminder, or contact action lacks permission, the agent can now explain the missing permission path instead of burning the turn on a timeout.</p><h2>Evidence From the PR</h2><p>The PR added <code>NodeServicePermissionTests</code> for <code>.notDetermined</code> permission states across Calendar, Reminders, and Contacts. It also reports simulator testing on iOS 26.5 and two real setup-code pairings against an isolated local Gateway.</p><p>The before-and-after proof is direct. Before the fix, a real paired-gateway <code>contacts.search</code> invocation opened the native Contacts prompt from the node call, and leaving it unanswered caused gateway timeout behavior. After the fix, <code>contacts.search</code>, <code>calendar.events</code>, and <code>reminders.list</code> immediately returned their permission-required errors with no native alert.</p><p>The granted-permission path was also checked: once permissions were granted from the appropriate UI surface, those same node calls succeeded.</p><h2>Bottom Line</h2><p>This is a clean boundary fix. OpenClaw's iOS node services now keep <code>node.invoke</code> prompt-free for Calendar, Reminders, and Contacts. Permission requests stay in the app's settings UI, while agent calls get fast, structured permission errors when access is missing.</p><p>For anyone using iOS as an OpenClaw node, <a href=\"https://github.com/openclaw/openclaw/pull/99477\">PR #99477</a> should make permission failures much easier to understand and recover from.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-ios-permission-prompts-stop.png\" alt=\"OpenClaw Stops iOS Node Permission Prompts\" /></p>",
      "date_published": "2026-07-03T23:18:00.000Z",
      "date_modified": "2026-07-09T08:12:14.650Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Stops",
        "Node",
        "Permission",
        "Prompts"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-ios-permission-prompts-stop.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-ios-permission-prompts-stop.png",
          "mime_type": "image/png",
          "title": "OpenClaw Stops iOS Node Permission Prompts cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-google-gemini-key-rotation/",
      "url": "https://openclawchronicles.com/posts/openclaw-google-gemini-key-rotation/",
      "title": "OpenClaw Rotates Google Gemini API Keys",
      "summary": "OpenClaw now rotates Google Gemini API keys for LLM streams, improving resilience when one key hits quota or rate limits.",
      "content_text": "OpenClaw's Google provider path gained a practical resilience fix today in [PR #97328, \"fix(google): rotate Gemini API keys for LLM requests\"](https://github.com/openclaw/openclaw/pull/97328). The patch makes Gemini LLM streaming use the same kind of key-rotation behavior that already existed for embeddings.\n\nThe result is a better failure story for users who configure multiple Gemini API keys. If the first key hits a rate limit or quota response, OpenClaw no longer has to fail the LLM stream immediately just because that first credential was exhausted.\n\n## What Changed\n\nPR #97328 fixes a mismatch between Gemini embedding requests and Gemini LLM streaming requests. The PR explains that users with multiple Gemini API keys configured could still see LLM streaming fail immediately when the first key hit a rate limit or quota response.\n\nThat is frustrating because key rotation already existed elsewhere. Embeddings could use the rotation helper, but the LLM stream path resolved only one key before sending the provider request.\n\nThe fix routes official Google Generative AI stream setup through OpenClaw's existing provider API-key rotation helper before SSE chunks are emitted. The PR is careful about the security boundary: environment-key rotation is allowed only for the official Google Generative AI HTTPS host, while Vertex and OAuth credential modes remain separate.\n\nFor operators, the practical benefit is better availability. If one configured Gemini key is rate-limited, OpenClaw has a chance to try the next eligible key before the model turn fails.\n\n## Why It Matters\n\nProvider integrations fail in ordinary ways: quota limits, rate limits, bad tokens, expired credentials, and noisy upstream diagnostics. The difference between a rough integration and a production-ready one is how predictably the agent handles those failures.\n\nThis Google fix improves that predictability where users are most likely to notice it: the live LLM stream. When an agent is mid-turn, a quota-limited first key should not necessarily be the end of the request if the operator has already provided other eligible keys.\n\nThe PR is also careful about scope. It does not blur OAuth, Vertex, and API-key modes together. It improves the official Google Generative AI HTTPS path while keeping credential boundaries explicit.\n\nThat makes the change both useful and conservative. OpenClaw gets better availability for a common Gemini setup without turning key rotation into a broad provider credential rewrite.\n\n## Evidence and Risk\n\nThe PR carries the `extensions: google`, `proof: sufficient`, `merge-risk: auth-provider`, and `merge-risk: security-boundary` labels. That combination is a good summary of the work: it touches a sensitive provider boundary, but it comes with enough proof for maintainers to merge it.\n\nThe body describes the fix as routing official Google Generative AI stream setup through the existing provider API-key rotation helper before SSE chunks are emitted. It also calls out what did not change: Vertex, OAuth JSON credentials, OAuth personal credentials, and non-official hosts stay outside the env-key rotation path.\n\nFor operators, that matters. Provider hardening should not surprise credential owners. A key-rotation fix is only a win if it stays inside the credential mode the user actually selected.\n\n## Bottom Line\n\nOpenClaw's Google provider path is getting more flexible where flexibility helps: retrying Gemini LLM streams with another configured API key when the first one hits quota or rate-limit pressure.\n\nFor Gemini users with multiple keys configured, [PR #97328](https://github.com/openclaw/openclaw/pull/97328) is a meaningful maintenance win ahead of the next OpenClaw release.",
      "content_html": "<p>OpenClaw's Google provider path gained a practical resilience fix today in <a href=\"https://github.com/openclaw/openclaw/pull/97328\">PR #97328, \"fix(google): rotate Gemini API keys for LLM requests\"</a>. The patch makes Gemini LLM streaming use the same kind of key-rotation behavior that already existed for embeddings.</p><p>The result is a better failure story for users who configure multiple Gemini API keys. If the first key hits a rate limit or quota response, OpenClaw no longer has to fail the LLM stream immediately just because that first credential was exhausted.</p><h2>What Changed</h2><p>PR #97328 fixes a mismatch between Gemini embedding requests and Gemini LLM streaming requests. The PR explains that users with multiple Gemini API keys configured could still see LLM streaming fail immediately when the first key hit a rate limit or quota response.</p><p>That is frustrating because key rotation already existed elsewhere. Embeddings could use the rotation helper, but the LLM stream path resolved only one key before sending the provider request.</p><p>The fix routes official Google Generative AI stream setup through OpenClaw's existing provider API-key rotation helper before SSE chunks are emitted. The PR is careful about the security boundary: environment-key rotation is allowed only for the official Google Generative AI HTTPS host, while Vertex and OAuth credential modes remain separate.</p><p>For operators, the practical benefit is better availability. If one configured Gemini key is rate-limited, OpenClaw has a chance to try the next eligible key before the model turn fails.</p><h2>Why It Matters</h2><p>Provider integrations fail in ordinary ways: quota limits, rate limits, bad tokens, expired credentials, and noisy upstream diagnostics. The difference between a rough integration and a production-ready one is how predictably the agent handles those failures.</p><p>This Google fix improves that predictability where users are most likely to notice it: the live LLM stream. When an agent is mid-turn, a quota-limited first key should not necessarily be the end of the request if the operator has already provided other eligible keys.</p><p>The PR is also careful about scope. It does not blur OAuth, Vertex, and API-key modes together. It improves the official Google Generative AI HTTPS path while keeping credential boundaries explicit.</p><p>That makes the change both useful and conservative. OpenClaw gets better availability for a common Gemini setup without turning key rotation into a broad provider credential rewrite.</p><h2>Evidence and Risk</h2><p>The PR carries the <code>extensions: google</code>, <code>proof: sufficient</code>, <code>merge-risk: auth-provider</code>, and <code>merge-risk: security-boundary</code> labels. That combination is a good summary of the work: it touches a sensitive provider boundary, but it comes with enough proof for maintainers to merge it.</p><p>The body describes the fix as routing official Google Generative AI stream setup through the existing provider API-key rotation helper before SSE chunks are emitted. It also calls out what did not change: Vertex, OAuth JSON credentials, OAuth personal credentials, and non-official hosts stay outside the env-key rotation path.</p><p>For operators, that matters. Provider hardening should not surprise credential owners. A key-rotation fix is only a win if it stays inside the credential mode the user actually selected.</p><h2>Bottom Line</h2><p>OpenClaw's Google provider path is getting more flexible where flexibility helps: retrying Gemini LLM streams with another configured API key when the first one hits quota or rate-limit pressure.</p><p>For Gemini users with multiple keys configured, <a href=\"https://github.com/openclaw/openclaw/pull/97328\">PR #97328</a> is a meaningful maintenance win ahead of the next OpenClaw release.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-google-gemini-key-rotation.png\" alt=\"OpenClaw Rotates Google Gemini API Keys\" /></p>",
      "date_published": "2026-07-03T23:12:00.000Z",
      "date_modified": "2026-07-09T08:12:14.650Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Rotates",
        "Google",
        "Gemini",
        "Keys"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-google-gemini-key-rotation.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-google-gemini-key-rotation.png",
          "mime_type": "image/png",
          "title": "OpenClaw Rotates Google Gemini API Keys cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-slack-session-conflict-retry/",
      "url": "https://openclawchronicles.com/posts/openclaw-slack-session-conflict-retry/",
      "title": "OpenClaw Fixes Slack Session Conflict Retry",
      "summary": "OpenClaw merged a P1 Slack delivery fix that retries transient reply-session conflicts instead of losing inbound messages.",
      "content_text": "OpenClaw's Slack integration picked up a focused P1 reliability repair tonight in [PR #99647, \"Fix Slack retry for session init conflicts\"](https://github.com/openclaw/openclaw/pull/99647). The patch targets a narrow but painful failure mode: a transient reply-session initialization conflict wrapped inside a Slack dispatch failure.\n\nThe practical effect is simple. When Slack inbound handling hits that conflict, OpenClaw now treats it as retryable work instead of recording the inbound delivery as handled. The debounce flush is re-enqueued with bounded backoff, giving the same message another chance to land once the session conflict clears.\n\n## What Changed\n\nThe PR body says the fix does three things:\n\n- It detects wrapped Slack dispatch failures whose underlying cause is a reply-session initialization conflict.\n- It avoids recording inbound delivery for that transient failure.\n- It re-enqueues the Slack debounce flush with bounded backoff.\n\nThat last point matters. Slack messages can arrive in bursts, and OpenClaw's monitor has to decide whether a failure means \"try this again shortly\" or \"this event is done.\" Treating a temporary session-initialization conflict as done would make the message disappear from the agent's point of view.\n\nWith this patch, the failure stays in the retry lane. The agent does not need a new user mention, a manual replay, or an operator restart just because the first attempt collided with a session boundary.\n\n## Why Slack Session State Is Fragile\n\nSlack is one of OpenClaw's most important channels because it is where many teams run long-lived work threads. Those threads are also where subtle state bugs show up. A single inbound message may need to pass through mention detection, thread participation checks, debounce handling, reply-session lookup, and downstream model execution.\n\nPR #99647 is about the handoff between inbound Slack events and reply-session initialization. If OpenClaw is already creating or updating the target session, a second message can hit a conflict at exactly the wrong moment. The right behavior is not to pretend the Slack event was successfully processed. It is to back off, keep the event eligible, and retry after the temporary conflict has time to clear.\n\nThat is what this patch does.\n\n## The Verification Trail\n\nThe PR includes regression coverage for the specific wrapped-error case: `Slack dispatch failed` followed by a `reply session initialization conflicted` cause. It also lists targeted formatting and Vitest commands against the Slack monitor message-handler code and tests.\n\nThe labels are a useful signal too. GitHub marks the PR as `P1`, `channel: slack`, and `rating: diamond lobster`, with maintainer authorship. That combination makes it stronger than an ordinary cleanup PR because the affected surface is user-visible message delivery.\n\n## Bottom Line\n\nThis is not a new Slack feature, but it is the kind of operational fix that makes OpenClaw feel more dependable in real team channels. A transient session conflict should delay a reply, not erase the inbound work.\n\nFor Slack-heavy OpenClaw deployments, [PR #99647](https://github.com/openclaw/openclaw/pull/99647) is worth watching in the next release notes, especially if agents have ever missed a thread reply during busy channel activity.",
      "content_html": "<p>OpenClaw's Slack integration picked up a focused P1 reliability repair tonight in <a href=\"https://github.com/openclaw/openclaw/pull/99647\">PR #99647, \"Fix Slack retry for session init conflicts\"</a>. The patch targets a narrow but painful failure mode: a transient reply-session initialization conflict wrapped inside a Slack dispatch failure.</p><p>The practical effect is simple. When Slack inbound handling hits that conflict, OpenClaw now treats it as retryable work instead of recording the inbound delivery as handled. The debounce flush is re-enqueued with bounded backoff, giving the same message another chance to land once the session conflict clears.</p><h2>What Changed</h2><p>The PR body says the fix does three things:</p><ul><li>It detects wrapped Slack dispatch failures whose underlying cause is a reply-session initialization conflict.</li><li>It avoids recording inbound delivery for that transient failure.</li><li>It re-enqueues the Slack debounce flush with bounded backoff.</li></ul><p>That last point matters. Slack messages can arrive in bursts, and OpenClaw's monitor has to decide whether a failure means \"try this again shortly\" or \"this event is done.\" Treating a temporary session-initialization conflict as done would make the message disappear from the agent's point of view.</p><p>With this patch, the failure stays in the retry lane. The agent does not need a new user mention, a manual replay, or an operator restart just because the first attempt collided with a session boundary.</p><h2>Why Slack Session State Is Fragile</h2><p>Slack is one of OpenClaw's most important channels because it is where many teams run long-lived work threads. Those threads are also where subtle state bugs show up. A single inbound message may need to pass through mention detection, thread participation checks, debounce handling, reply-session lookup, and downstream model execution.</p><p>PR #99647 is about the handoff between inbound Slack events and reply-session initialization. If OpenClaw is already creating or updating the target session, a second message can hit a conflict at exactly the wrong moment. The right behavior is not to pretend the Slack event was successfully processed. It is to back off, keep the event eligible, and retry after the temporary conflict has time to clear.</p><p>That is what this patch does.</p><h2>The Verification Trail</h2><p>The PR includes regression coverage for the specific wrapped-error case: <code>Slack dispatch failed</code> followed by a <code>reply session initialization conflicted</code> cause. It also lists targeted formatting and Vitest commands against the Slack monitor message-handler code and tests.</p><p>The labels are a useful signal too. GitHub marks the PR as <code>P1</code>, <code>channel: slack</code>, and <code>rating: diamond lobster</code>, with maintainer authorship. That combination makes it stronger than an ordinary cleanup PR because the affected surface is user-visible message delivery.</p><h2>Bottom Line</h2><p>This is not a new Slack feature, but it is the kind of operational fix that makes OpenClaw feel more dependable in real team channels. A transient session conflict should delay a reply, not erase the inbound work.</p><p>For Slack-heavy OpenClaw deployments, <a href=\"https://github.com/openclaw/openclaw/pull/99647\">PR #99647</a> is worth watching in the next release notes, especially if agents have ever missed a thread reply during busy channel activity.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-slack-session-conflict-retry.png\" alt=\"OpenClaw Fixes Slack Session Conflict Retry\" /></p>",
      "date_published": "2026-07-03T23:05:00.000Z",
      "date_modified": "2026-07-09T08:12:14.650Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Fixes",
        "Slack",
        "Session",
        "Conflict",
        "Retry"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-slack-session-conflict-retry.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-slack-session-conflict-retry.png",
          "mime_type": "image/png",
          "title": "OpenClaw Fixes Slack Session Conflict Retry cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-3-ambient-room-transcripts/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-3-ambient-room-transcripts/",
      "title": "OpenClaw Ambient Groups Now Persist Chat Memory",
      "summary": "OpenClaw ambient group mode now persists room events as transcript rows, helping agents remember older chat while cutting repeated prompt cost.",
      "content_text": "OpenClaw merged [PR #99306, \"feat(auto-reply): persist ambient room events as transcript rows\"](https://github.com/openclaw/openclaw/pull/99306), a significant change for agents that quietly observe Telegram group rooms and decide when to speak.\n\nThe issue was straightforward: in ambient group mode, the agent could evaluate every unmentioned room message, but it was forced to forget those messages afterward. The PR says group knowledge lived only in a bounded per-turn chat window, with a default size of 50 messages, rebuilt into the uncached prompt tail on every turn.\n\nMessages older than that window were not persisted, so compaction could not summarize them and future turns could not recover them.\n\n## What Changed\n\nAmbient room events now become durable session transcript rows. Each observed room event persists as one user-role row in the same attributed shape used for the current event display line, such as `#id sender: body`.\n\nThe row is intentionally plain. The PR says there is no metadata prefix, no window snapshot, and no assistant row when the turn remains silent. Coalesced room events can persist one row containing each observed message as its own attributed line.\n\nThat makes the transcript the durable group chat log, not just a record of messages the agent answered.\n\n## The Watermark Invariant\n\nThe core of the change is a per-chat ambient watermark. It advances only after the transcript row is durably persisted, using a timestamp-first ordering with message ID as the tiebreaker.\n\nPrompt-facing consumers of raw group history then exclude messages at or before the watermark. That includes group-history entries, cache-derived chat windows, room-event inbound history, and recovered-thread paths.\n\nThe goal is to prevent duplication. Once a message is owned by the transcript, the old raw-window path should stop injecting it again. The PR notes one intentional exception: explicit reply targets remain visible even if transcript-owned, so the model never sees a reply without the quoted context.\n\n## Why It Matters\n\nAmbient group mode is valuable because the agent can observe without interrupting. But observation is much less useful if the agent loses older context or repeatedly pays for the same message window.\n\nWith transcript persistence, older room context can participate in normal compaction. That gives the agent a path to retain the gist of group conversations beyond the short raw window.\n\nThe token economics also improve. The PR describes the net effect as each group message costing its tokens once, then becoming prompt-cache-hit on later turns instead of being rebuilt into the uncached tail every time.\n\n## Scope and Behavior\n\nThis is a cutover for ambient mode, not a new setting. Mention-only mode is untouched because the persist hook is wired only for room events.\n\nSilent turns remain silent. The change removes the room-event user-suppression special casing that prevented persistence, but it still suppresses transcript-only assistant rows when the agent chooses not to respond.\n\nCore owns the watermark, while the channel reads it through the documented plugin SDK session-store runtime. That keeps the transcript boundary channel-agnostic instead of making Telegram invent its own memory layer.\n\n## Evidence\n\nThe PR reports regression coverage for row shape, silent-turn assistant suppression, watermark advancement, dedupe boundaries, consecutive user rows, CLI session reseed, embedded replay, and `strip-inbound-meta` pass-through.\n\nIt also notes two autoreview rounds that found raw-window watermark bypasses; both were fixed and covered with regression tests that assert against final assembled prompt text.\n\n## Bottom Line\n\nPR #99306 gives ambient group agents a more durable memory contract.\n\nOpenClaw can now observe group chat, persist the observed messages as transcript rows, compact them later, and avoid repeatedly feeding already-owned room history back into each new prompt.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99306\">PR #99306, \"feat(auto-reply): persist ambient room events as transcript rows\"</a>, a significant change for agents that quietly observe Telegram group rooms and decide when to speak.</p><p>The issue was straightforward: in ambient group mode, the agent could evaluate every unmentioned room message, but it was forced to forget those messages afterward. The PR says group knowledge lived only in a bounded per-turn chat window, with a default size of 50 messages, rebuilt into the uncached prompt tail on every turn.</p><p>Messages older than that window were not persisted, so compaction could not summarize them and future turns could not recover them.</p><h2>What Changed</h2><p>Ambient room events now become durable session transcript rows. Each observed room event persists as one user-role row in the same attributed shape used for the current event display line, such as <code>#id sender: body</code>.</p><p>The row is intentionally plain. The PR says there is no metadata prefix, no window snapshot, and no assistant row when the turn remains silent. Coalesced room events can persist one row containing each observed message as its own attributed line.</p><p>That makes the transcript the durable group chat log, not just a record of messages the agent answered.</p><h2>The Watermark Invariant</h2><p>The core of the change is a per-chat ambient watermark. It advances only after the transcript row is durably persisted, using a timestamp-first ordering with message ID as the tiebreaker.</p><p>Prompt-facing consumers of raw group history then exclude messages at or before the watermark. That includes group-history entries, cache-derived chat windows, room-event inbound history, and recovered-thread paths.</p><p>The goal is to prevent duplication. Once a message is owned by the transcript, the old raw-window path should stop injecting it again. The PR notes one intentional exception: explicit reply targets remain visible even if transcript-owned, so the model never sees a reply without the quoted context.</p><h2>Why It Matters</h2><p>Ambient group mode is valuable because the agent can observe without interrupting. But observation is much less useful if the agent loses older context or repeatedly pays for the same message window.</p><p>With transcript persistence, older room context can participate in normal compaction. That gives the agent a path to retain the gist of group conversations beyond the short raw window.</p><p>The token economics also improve. The PR describes the net effect as each group message costing its tokens once, then becoming prompt-cache-hit on later turns instead of being rebuilt into the uncached tail every time.</p><h2>Scope and Behavior</h2><p>This is a cutover for ambient mode, not a new setting. Mention-only mode is untouched because the persist hook is wired only for room events.</p><p>Silent turns remain silent. The change removes the room-event user-suppression special casing that prevented persistence, but it still suppresses transcript-only assistant rows when the agent chooses not to respond.</p><p>Core owns the watermark, while the channel reads it through the documented plugin SDK session-store runtime. That keeps the transcript boundary channel-agnostic instead of making Telegram invent its own memory layer.</p><h2>Evidence</h2><p>The PR reports regression coverage for row shape, silent-turn assistant suppression, watermark advancement, dedupe boundaries, consecutive user rows, CLI session reseed, embedded replay, and <code>strip-inbound-meta</code> pass-through.</p><p>It also notes two autoreview rounds that found raw-window watermark bypasses; both were fixed and covered with regression tests that assert against final assembled prompt text.</p><h2>Bottom Line</h2><p>PR #99306 gives ambient group agents a more durable memory contract.</p><p>OpenClaw can now observe group chat, persist the observed messages as transcript rows, compact them later, and avoid repeatedly feeding already-owned room history back into each new prompt.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-ambient-room-transcripts.png\" alt=\"OpenClaw Ambient Groups Now Persist Chat Memory\" /></p>",
      "date_published": "2026-07-03T08:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Guides",
        "Memory",
        "Ambient",
        "Groups",
        "Persist",
        "Chat"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-ambient-room-transcripts.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-ambient-room-transcripts.png",
          "mime_type": "image/png",
          "title": "OpenClaw Ambient Groups Now Persist Chat Memory cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-3-android-gateway-recovery/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-3-android-gateway-recovery/",
      "title": "OpenClaw Android Shows Exact Gateway Recovery",
      "summary": "OpenClaw Android now distinguishes stale credentials, expired setup codes, and pending node approvals with targeted Gateway recovery actions.",
      "content_text": "OpenClaw merged [PR #99414, \"fix(android): expose exact gateway recovery actions\"](https://github.com/openclaw/openclaw/pull/99414) shortly before the July 3rd morning scan, tightening one of the Android app's most important setup and recovery flows.\n\nThe old behavior grouped several different failures under generic retry states. A stale credential, an expired setup code, and a pending node capability approval could all leave the user staring at a recovery screen that did not explain the exact next action.\n\nThat is especially frustrating for mobile nodes. Android may be acting as a notification bridge, a companion client, or a device-backed node surface. When pairing or reconnecting fails, the app needs to tell the user whether to scan, edit, approve, or simply retry.\n\n## What Changed\n\nThe Gateway can now include a pending node request ID, but only under a narrow condition: a signed read-scoped Android client must be reading its own device-backed node. Pending capability declarations for other nodes remain redacted.\n\nAndroid then carries the phone's capability approval state and optional request ID as one closed value. Onboarding and Nodes & Devices use the same command mapper, so a valid request ID can produce an exact host command:\n\n`openclaw nodes approve <id>`\n\nIf the ID is malformed, unavailable, expired, or no longer applicable, the app falls back to the safer `openclaw nodes status` guidance.\n\n## Better Failure Routing\n\nThe recovery flow now separates the common cases:\n\n- Expired bootstrap tokens route users to scan a fresh setup code.\n- Stale stored client credentials route users to edit the connection.\n- Gateway-host authentication configuration stays on a retry path after the host-side issue is fixed.\n- Pending node approval can show the exact command when it is safe to expose.\n\nThe PR also says Android clears cached approval IDs when the target changes, ages cached commands back to the status fallback, and refreshes `node.list` while approval remains pending.\n\nThat matters because approval IDs are gateway-local and short-lived. Treating them as durable instructions would make the recovery UI misleading, and potentially unsafe, after a connection or target changes.\n\n## Why It Matters\n\nThis is a small surface with a large trust impact. A user who already knows what went wrong can recover quickly. A user who does not know whether the phone needs a new QR code, a corrected token, or a host-side approval command should not have to guess.\n\nThe implementation also preserves the boundary between the current phone and other devices. The request ID is not a broad introspection feature for any read-only client; it is scoped to the signed identity that owns the pending device-backed node.\n\nThat keeps the convenience of exact recovery without turning pending node approvals into globally readable state.\n\n## Evidence\n\nThe PR reports Gateway authorization tests proving unrelated read-only clients cannot see pending request IDs, while the same signed device identity can see only its own request ID in `node.list` and `node.describe`.\n\nFocused proof included 20 Gateway node-pairing authorization tests, Android tests for node approval, onboarding recovery, and Settings, plus ktlint and Play debug APK assembly.\n\nThe real-source Gateway and Android emulator matrix covered pending node approval, expired bootstrap handling, stale-token handling, and launching the recovery scanner from the Play APK.\n\n## Bottom Line\n\nPR #99414 makes Android Gateway recovery more specific and less noisy.\n\nInstead of one vague retry loop, OpenClaw can now tell Android users when to scan a fresh setup code, edit saved authentication, run an exact node approval command, or retry after host-side configuration is corrected.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99414\">PR #99414, \"fix(android): expose exact gateway recovery actions\"</a> shortly before the July 3rd morning scan, tightening one of the Android app's most important setup and recovery flows.</p><p>The old behavior grouped several different failures under generic retry states. A stale credential, an expired setup code, and a pending node capability approval could all leave the user staring at a recovery screen that did not explain the exact next action.</p><p>That is especially frustrating for mobile nodes. Android may be acting as a notification bridge, a companion client, or a device-backed node surface. When pairing or reconnecting fails, the app needs to tell the user whether to scan, edit, approve, or simply retry.</p><h2>What Changed</h2><p>The Gateway can now include a pending node request ID, but only under a narrow condition: a signed read-scoped Android client must be reading its own device-backed node. Pending capability declarations for other nodes remain redacted.</p><p>Android then carries the phone's capability approval state and optional request ID as one closed value. Onboarding and Nodes & Devices use the same command mapper, so a valid request ID can produce an exact host command:</p><p><code>openclaw nodes approve <id></code></p><p>If the ID is malformed, unavailable, expired, or no longer applicable, the app falls back to the safer <code>openclaw nodes status</code> guidance.</p><h2>Better Failure Routing</h2><p>The recovery flow now separates the common cases:</p><ul><li>Expired bootstrap tokens route users to scan a fresh setup code.</li><li>Stale stored client credentials route users to edit the connection.</li><li>Gateway-host authentication configuration stays on a retry path after the host-side issue is fixed.</li><li>Pending node approval can show the exact command when it is safe to expose.</li></ul><p>The PR also says Android clears cached approval IDs when the target changes, ages cached commands back to the status fallback, and refreshes <code>node.list</code> while approval remains pending.</p><p>That matters because approval IDs are gateway-local and short-lived. Treating them as durable instructions would make the recovery UI misleading, and potentially unsafe, after a connection or target changes.</p><h2>Why It Matters</h2><p>This is a small surface with a large trust impact. A user who already knows what went wrong can recover quickly. A user who does not know whether the phone needs a new QR code, a corrected token, or a host-side approval command should not have to guess.</p><p>The implementation also preserves the boundary between the current phone and other devices. The request ID is not a broad introspection feature for any read-only client; it is scoped to the signed identity that owns the pending device-backed node.</p><p>That keeps the convenience of exact recovery without turning pending node approvals into globally readable state.</p><h2>Evidence</h2><p>The PR reports Gateway authorization tests proving unrelated read-only clients cannot see pending request IDs, while the same signed device identity can see only its own request ID in <code>node.list</code> and <code>node.describe</code>.</p><p>Focused proof included 20 Gateway node-pairing authorization tests, Android tests for node approval, onboarding recovery, and Settings, plus ktlint and Play debug APK assembly.</p><p>The real-source Gateway and Android emulator matrix covered pending node approval, expired bootstrap handling, stale-token handling, and launching the recovery scanner from the Play APK.</p><h2>Bottom Line</h2><p>PR #99414 makes Android Gateway recovery more specific and less noisy.</p><p>Instead of one vague retry loop, OpenClaw can now tell Android users when to scan a fresh setup code, edit saved authentication, run an exact node approval command, or retry after host-side configuration is corrected.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-android-gateway-recovery.png\" alt=\"OpenClaw Android Shows Exact Gateway Recovery\" /></p>",
      "date_published": "2026-07-03T08:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Android",
        "Shows",
        "Exact",
        "Gateway",
        "Recovery"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-android-gateway-recovery.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-android-gateway-recovery.png",
          "mime_type": "image/png",
          "title": "OpenClaw Android Shows Exact Gateway Recovery cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-3-control-ui-sidebar/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-3-control-ui-sidebar/",
      "title": "OpenClaw Control UI Gets a Session-First Sidebar",
      "summary": "OpenClaw's Control UI now centers sessions in the sidebar, adds a compact context ring, and softens the default light theme.",
      "content_text": "OpenClaw merged [PR #99289, \"feat: session-first sidebar, compact context ring, and warm light theme for the Control UI\"](https://github.com/openclaw/openclaw/pull/99289) just before the July 3rd morning scan, shipping a substantial usability pass for the web Control UI.\n\nThe change targets one of the most repeated operator actions: finding, switching, and returning to active sessions. Before the merge, the PR says session switching was buried under a 14-tab page nav, a small dropdown, and a recents list that could stay empty on a cold `/chat` load.\n\nThat is a sharp pain point for a product built around long-running agents. If the user cannot quickly see which session is live, which session is recent, and how much context is left, the interface adds friction to every follow-up.\n\n## What Changed\n\nThe expanded sidebar now treats sessions as the main chat entry point. It shows a `+ New session` action, a ten-row recent session list, a compact session search button, and an `All sessions` path. The current session can stay pinned above recents, even when lists are capped, filtered, archived, or otherwise replaced.\n\nThe PR also moves the full session picker behind search and makes cold chat entry hydrate sessions in the background. That background load is deliberately scoped so a stale session-list snapshot cannot clear live stream state or disable the New Session action.\n\nThe old chat nav group is removed from the expanded sidebar because, in the new model, the session list is chat. The collapsed rail keeps its icon for compact navigation.\n\n## Context Moves Into the Composer\n\nContext usage also gets a smaller, more local home. Instead of occupying a full-width pill above the composer, usage becomes a compact ring and percentage near the send control, with fuller detail available in a tooltip.\n\nThat makes the signal easier to scan without forcing context pressure to dominate the conversation surface. The PR notes that the compact button still appears when pressure is high, so the warning path remains visible when it matters.\n\n## A Calmer Light Theme\n\nPR #99289 also adjusts the default light palette from cool gray and alarm red toward warm paper, warm gray borders, and a terracotta accent. The PR reports accessibility checks for the new accent and text contrast, including a 4.9:1 accent-on-background ratio and stronger contrast for primary text.\n\nSmaller refinements round out the release: the sidebar brand drops the `CONTROL` eyebrow, breadcrumbs stop repeating `OpenClaw › OpenClaw` when the agent is named OpenClaw, settings becomes an icon-only chip, and the send button becomes a filled circle.\n\n## Why It Matters\n\nThis is not just visual polish. It changes the information architecture around the unit operators touch most often: the session.\n\nFor teams running multiple agents, the sidebar keeps an agent filter in the sessions section. For single-agent installs, that filter stays out of the way. The provider quota pill also moves into the sidebar footer so it remains available outside the chat tab.\n\nThe PR body says the change removes the old sidebar dropdown select, `sessionSwitcherOnly` and `compact` picker variants, and unused sidebar-search CSS, while ending at a net reduction of 64 lines overall after generated i18n changes.\n\n## Evidence\n\nThe PR includes before-and-after screenshots for light and dark mode, plus a published artifact manifest. Its test evidence covers `pnpm tsgo:test:ui`, unit and browser suites, mocked-gateway E2E coverage for chat flow, picker pagination, search, the quota pill, background hydration, and the pinned active row.\n\nCodex autoreview also ran multiple passes, with the final pass reporting no accepted actionable findings.\n\n## Bottom Line\n\nOpenClaw's Control UI is moving toward a session-first operating surface: fewer buried controls, more visible recents, clearer context pressure, and a lighter default visual tone.\n\nFor daily operators, that should make the web UI feel less like a settings dashboard and more like an agent workspace.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/99289\">PR #99289, \"feat: session-first sidebar, compact context ring, and warm light theme for the Control UI\"</a> just before the July 3rd morning scan, shipping a substantial usability pass for the web Control UI.</p><p>The change targets one of the most repeated operator actions: finding, switching, and returning to active sessions. Before the merge, the PR says session switching was buried under a 14-tab page nav, a small dropdown, and a recents list that could stay empty on a cold <code>/chat</code> load.</p><p>That is a sharp pain point for a product built around long-running agents. If the user cannot quickly see which session is live, which session is recent, and how much context is left, the interface adds friction to every follow-up.</p><h2>What Changed</h2><p>The expanded sidebar now treats sessions as the main chat entry point. It shows a <code>+ New session</code> action, a ten-row recent session list, a compact session search button, and an <code>All sessions</code> path. The current session can stay pinned above recents, even when lists are capped, filtered, archived, or otherwise replaced.</p><p>The PR also moves the full session picker behind search and makes cold chat entry hydrate sessions in the background. That background load is deliberately scoped so a stale session-list snapshot cannot clear live stream state or disable the New Session action.</p><p>The old chat nav group is removed from the expanded sidebar because, in the new model, the session list is chat. The collapsed rail keeps its icon for compact navigation.</p><h2>Context Moves Into the Composer</h2><p>Context usage also gets a smaller, more local home. Instead of occupying a full-width pill above the composer, usage becomes a compact ring and percentage near the send control, with fuller detail available in a tooltip.</p><p>That makes the signal easier to scan without forcing context pressure to dominate the conversation surface. The PR notes that the compact button still appears when pressure is high, so the warning path remains visible when it matters.</p><h2>A Calmer Light Theme</h2><p>PR #99289 also adjusts the default light palette from cool gray and alarm red toward warm paper, warm gray borders, and a terracotta accent. The PR reports accessibility checks for the new accent and text contrast, including a 4.9:1 accent-on-background ratio and stronger contrast for primary text.</p><p>Smaller refinements round out the release: the sidebar brand drops the <code>CONTROL</code> eyebrow, breadcrumbs stop repeating <code>OpenClaw › OpenClaw</code> when the agent is named OpenClaw, settings becomes an icon-only chip, and the send button becomes a filled circle.</p><h2>Why It Matters</h2><p>This is not just visual polish. It changes the information architecture around the unit operators touch most often: the session.</p><p>For teams running multiple agents, the sidebar keeps an agent filter in the sessions section. For single-agent installs, that filter stays out of the way. The provider quota pill also moves into the sidebar footer so it remains available outside the chat tab.</p><p>The PR body says the change removes the old sidebar dropdown select, <code>sessionSwitcherOnly</code> and <code>compact</code> picker variants, and unused sidebar-search CSS, while ending at a net reduction of 64 lines overall after generated i18n changes.</p><h2>Evidence</h2><p>The PR includes before-and-after screenshots for light and dark mode, plus a published artifact manifest. Its test evidence covers <code>pnpm tsgo:test:ui</code>, unit and browser suites, mocked-gateway E2E coverage for chat flow, picker pagination, search, the quota pill, background hydration, and the pinned active row.</p><p>Codex autoreview also ran multiple passes, with the final pass reporting no accepted actionable findings.</p><h2>Bottom Line</h2><p>OpenClaw's Control UI is moving toward a session-first operating surface: fewer buried controls, more visible recents, clearer context pressure, and a lighter default visual tone.</p><p>For daily operators, that should make the web UI feel less like a settings dashboard and more like an agent workspace.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-control-ui-sidebar.png\" alt=\"OpenClaw Control UI Gets a Session-First Sidebar\" /></p>",
      "date_published": "2026-07-03T08:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Control",
        "Gets",
        "Session",
        "First",
        "Sidebar"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-control-ui-sidebar.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-3-control-ui-sidebar.png",
          "mime_type": "image/png",
          "title": "OpenClaw Control UI Gets a Session-First Sidebar cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-reply-session-conflict-fix/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-reply-session-conflict-fix/",
      "title": "OpenClaw Narrows Reply Session Conflict Checks",
      "summary": "OpenClaw now avoids false reply-session initialization conflicts while preserving real session rotation and concurrent metadata updates.",
      "content_text": "OpenClaw merged [PR #98835, \"fix(config/sessions): narrow reply-session initialization revision to identity fields\"](https://github.com/openclaw/openclaw/pull/98835) on July 2nd, fixing a P1 session-state and message-delivery failure.\n\nThe user-visible symptom was rough: ongoing sessions could fail with `reply session initialization conflicted for agent:main:main` until the Gateway was restarted.\n\nAccording to the PR, the conflict came from the guarded reply-session initialization path comparing the full persisted session entry between snapshot and commit. That was too broad for a live system where many pieces of metadata can legitimately change while a reply session is being initialized.\n\n## What Changed\n\nThe initialization guard now checks only the identity fields that matter for detecting a real rotation: `sessionId` and `sessionFile`.\n\nIf those identity fields still match, the commit path can proceed. Metadata that changed after the snapshot is carried forward through `mergeConcurrentReplySessionMetadata`, while fields intentionally changed by the prepared turn still win.\n\nThat preserves important reset behavior. `/new` and `/reset` can still clear recovered auto-fallback provider or model overrides, runtime model caches, and context-budget state as before.\n\nThe PR also treats an absent field and an own `undefined` field as equivalent when deciding whether the prepared entry left a snapshot field unchanged. That prevents incidental optional `undefined` values from overwriting concurrent additions.\n\n## Why It Matters\n\nReply sessions are shared state. During normal operation, heartbeat metadata, pending-delivery metadata, updated timestamps, context details, and other fields can move while a turn is being prepared.\n\nThose updates should not be mistaken for a session rotation. A rotation means the actual identity changed. A heartbeat or delivery metadata update means the same session is still alive and carrying new information.\n\nBy narrowing the conflict check to identity fields, OpenClaw keeps the protection that matters without rejecting healthy same-session activity.\n\n## User Impact\n\nThe practical impact is less brittle session recovery.\n\nSame-session background activity should no longer break reply initialization. Real rotations are still detected and retried. Concurrent heartbeat, delivery, context, and optional metadata written after the snapshot should no longer be overwritten by the initialization commit.\n\nFor users, that means fewer \"restart the Gateway\" moments when an active session hits a timing race between message delivery and session initialization.\n\n## Evidence\n\nThe PR adds a deterministic two-process behavior proof at the production session-store and accessor boundary. The parent process seeds a real temporary `sessions.json`, the child process loads a reply-session initialization snapshot, the parent writes same-session metadata, and the child commits using its held snapshot.\n\nThe expected fixed behavior is `ok: true`; a stale-snapshot result would reproduce the conflict class.\n\nThe PR also reports an exploratory real-Gateway proof, focused regression coverage for stale snapshots and concurrent metadata, formatting and lint checks, `git diff --check`, autoreview, and a green active CI set including real behavior proof and session accessor boundary checks.\n\n## Bottom Line\n\nPR #98835 makes reply-session initialization judge the right thing: whether the session identity changed.\n\nThat is a small conceptual shift with a large reliability payoff. OpenClaw can now tolerate normal same-session metadata movement without confusing it for a conflicting initialization.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98835\">PR #98835, \"fix(config/sessions): narrow reply-session initialization revision to identity fields\"</a> on July 2nd, fixing a P1 session-state and message-delivery failure.</p><p>The user-visible symptom was rough: ongoing sessions could fail with <code>reply session initialization conflicted for agent:main:main</code> until the Gateway was restarted.</p><p>According to the PR, the conflict came from the guarded reply-session initialization path comparing the full persisted session entry between snapshot and commit. That was too broad for a live system where many pieces of metadata can legitimately change while a reply session is being initialized.</p><h2>What Changed</h2><p>The initialization guard now checks only the identity fields that matter for detecting a real rotation: <code>sessionId</code> and <code>sessionFile</code>.</p><p>If those identity fields still match, the commit path can proceed. Metadata that changed after the snapshot is carried forward through <code>mergeConcurrentReplySessionMetadata</code>, while fields intentionally changed by the prepared turn still win.</p><p>That preserves important reset behavior. <code>/new</code> and <code>/reset</code> can still clear recovered auto-fallback provider or model overrides, runtime model caches, and context-budget state as before.</p><p>The PR also treats an absent field and an own <code>undefined</code> field as equivalent when deciding whether the prepared entry left a snapshot field unchanged. That prevents incidental optional <code>undefined</code> values from overwriting concurrent additions.</p><h2>Why It Matters</h2><p>Reply sessions are shared state. During normal operation, heartbeat metadata, pending-delivery metadata, updated timestamps, context details, and other fields can move while a turn is being prepared.</p><p>Those updates should not be mistaken for a session rotation. A rotation means the actual identity changed. A heartbeat or delivery metadata update means the same session is still alive and carrying new information.</p><p>By narrowing the conflict check to identity fields, OpenClaw keeps the protection that matters without rejecting healthy same-session activity.</p><h2>User Impact</h2><p>The practical impact is less brittle session recovery.</p><p>Same-session background activity should no longer break reply initialization. Real rotations are still detected and retried. Concurrent heartbeat, delivery, context, and optional metadata written after the snapshot should no longer be overwritten by the initialization commit.</p><p>For users, that means fewer \"restart the Gateway\" moments when an active session hits a timing race between message delivery and session initialization.</p><h2>Evidence</h2><p>The PR adds a deterministic two-process behavior proof at the production session-store and accessor boundary. The parent process seeds a real temporary <code>sessions.json</code>, the child process loads a reply-session initialization snapshot, the parent writes same-session metadata, and the child commits using its held snapshot.</p><p>The expected fixed behavior is <code>ok: true</code>; a stale-snapshot result would reproduce the conflict class.</p><p>The PR also reports an exploratory real-Gateway proof, focused regression coverage for stale snapshots and concurrent metadata, formatting and lint checks, <code>git diff --check</code>, autoreview, and a green active CI set including real behavior proof and session accessor boundary checks.</p><h2>Bottom Line</h2><p>PR #98835 makes reply-session initialization judge the right thing: whether the session identity changed.</p><p>That is a small conceptual shift with a large reliability payoff. OpenClaw can now tolerate normal same-session metadata movement without confusing it for a conflicting initialization.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-reply-session-conflict-fix.png\" alt=\"OpenClaw Narrows Reply Session Conflict Checks\" /></p>",
      "date_published": "2026-07-02T23:03:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Narrows",
        "Reply",
        "Session",
        "Conflict",
        "Checks"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-reply-session-conflict-fix.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-reply-session-conflict-fix.png",
          "mime_type": "image/png",
          "title": "OpenClaw Narrows Reply Session Conflict Checks cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-managed-proxy-guarded-fetch/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-managed-proxy-guarded-fetch/",
      "title": "OpenClaw Fixes Managed Proxy Guarded Fetch",
      "summary": "OpenClaw strict guarded fetch now respects managed proxy-only sandboxes without local DNS failures blocking proxy enforcement.",
      "content_text": "OpenClaw merged [PR #98951, \"fix: strict guarded fetch fails before managed proxy DNS\"](https://github.com/openclaw/openclaw/pull/98951) on July 2nd, tightening a security-sensitive network path for proxy-only deployments.\n\nThe issue affected users running OpenClaw in managed proxy-only sandboxes. Strict or default guarded fetch calls could fail locally before reaching the managed proxy when local DNS could not resolve, disagreed with, or rejected a hostname.\n\nThat undermined the deployment model for environments where the proxy is supposed to own resolution and enforcement. The PR names channel and provider preflight, plugin HTTP paths, Google Chat, Mattermost, media, and web-tool paths as affected surfaces.\n\n## What Changed\n\nWhen `OPENCLAW_PROXY_ACTIVE=1` and the HTTP(S) environment proxy applies to the target URL, strict guarded fetch now keeps its pre-DNS hostname and IP-literal SSRF checks, then dispatches through the managed environment proxy without resolving the target locally.\n\nDirect strict mode still uses DNS pinning. `NO_PROXY` targets still use DNS pinning. Exact configured local-origin bypass candidates still resolve and pin DNS so loopback bypass policy remains enforced.\n\nIn other words, this is not a broad \"trust whatever proxy env vars say\" change. The proxy-aware path is limited to the OpenClaw managed proxy lifecycle.\n\n## Why It Matters\n\nGuarded fetch is a boundary feature. It exists so plugin, channel, provider, and tool paths can fetch remote resources without accidentally reaching private networks or metadata services.\n\nIn a managed proxy-only sandbox, though, local DNS may intentionally be incomplete or unavailable. The proxy is the component that sees the target hostname, resolves it, applies operator policy, and decides whether a tunnel should exist.\n\nBefore this PR, strict guarded fetch could still call the local resolver inside that managed-proxy branch. That meant a valid proxy-owned request could fail before the proxy had a chance to enforce policy.\n\n## Security Contract\n\nThe PR body is careful about the boundary: private IP literals and blocked hostnames are still rejected before fetch, redirects are still revalidated, and ordinary strict mode does not become proxy-aware just because proxy variables exist.\n\nThe deployment contract is that the managed proxy owns target DNS and blocks unsafe resolved addresses before opening a tunnel. The proof attached to the PR demonstrates this with public, loopback, RFC1918 private, and link-local target mappings.\n\nThat distinction matters. OpenClaw is not weakening guarded fetch checks; it is moving target DNS ownership to the managed proxy only when the managed proxy mode is active and applicable.\n\n## Evidence\n\nThe PR includes focused test coverage for SSRF and proxy environment behavior, plus lint, formatting, and `git diff --check` validation.\n\nThe behavioral proof used a local CONNECT proxy with `OPENCLAW_PROXY_ACTIVE=1`, proxy environment variables, an unresolvable hostname, and a lookup function that throws if local target DNS is attempted. The managed fetch returned a successful 200 response with zero local lookup calls.\n\nAdditional proof showed the proxy allowing a public destination while denying loopback, private, and link-local targets after proxy-side DNS resolution.\n\n## Bottom Line\n\nPR #98951 fixes a real operational mismatch between strict guarded fetch and managed proxy-only networking.\n\nFor operators using OpenClaw behind a managed proxy, fetches can now reach the enforcement boundary that is supposed to make the decision, without falling over on local DNS first.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98951\">PR #98951, \"fix: strict guarded fetch fails before managed proxy DNS\"</a> on July 2nd, tightening a security-sensitive network path for proxy-only deployments.</p><p>The issue affected users running OpenClaw in managed proxy-only sandboxes. Strict or default guarded fetch calls could fail locally before reaching the managed proxy when local DNS could not resolve, disagreed with, or rejected a hostname.</p><p>That undermined the deployment model for environments where the proxy is supposed to own resolution and enforcement. The PR names channel and provider preflight, plugin HTTP paths, Google Chat, Mattermost, media, and web-tool paths as affected surfaces.</p><h2>What Changed</h2><p>When <code>OPENCLAW_PROXY_ACTIVE=1</code> and the HTTP(S) environment proxy applies to the target URL, strict guarded fetch now keeps its pre-DNS hostname and IP-literal SSRF checks, then dispatches through the managed environment proxy without resolving the target locally.</p><p>Direct strict mode still uses DNS pinning. <code>NO_PROXY</code> targets still use DNS pinning. Exact configured local-origin bypass candidates still resolve and pin DNS so loopback bypass policy remains enforced.</p><p>In other words, this is not a broad \"trust whatever proxy env vars say\" change. The proxy-aware path is limited to the OpenClaw managed proxy lifecycle.</p><h2>Why It Matters</h2><p>Guarded fetch is a boundary feature. It exists so plugin, channel, provider, and tool paths can fetch remote resources without accidentally reaching private networks or metadata services.</p><p>In a managed proxy-only sandbox, though, local DNS may intentionally be incomplete or unavailable. The proxy is the component that sees the target hostname, resolves it, applies operator policy, and decides whether a tunnel should exist.</p><p>Before this PR, strict guarded fetch could still call the local resolver inside that managed-proxy branch. That meant a valid proxy-owned request could fail before the proxy had a chance to enforce policy.</p><h2>Security Contract</h2><p>The PR body is careful about the boundary: private IP literals and blocked hostnames are still rejected before fetch, redirects are still revalidated, and ordinary strict mode does not become proxy-aware just because proxy variables exist.</p><p>The deployment contract is that the managed proxy owns target DNS and blocks unsafe resolved addresses before opening a tunnel. The proof attached to the PR demonstrates this with public, loopback, RFC1918 private, and link-local target mappings.</p><p>That distinction matters. OpenClaw is not weakening guarded fetch checks; it is moving target DNS ownership to the managed proxy only when the managed proxy mode is active and applicable.</p><h2>Evidence</h2><p>The PR includes focused test coverage for SSRF and proxy environment behavior, plus lint, formatting, and <code>git diff --check</code> validation.</p><p>The behavioral proof used a local CONNECT proxy with <code>OPENCLAW_PROXY_ACTIVE=1</code>, proxy environment variables, an unresolvable hostname, and a lookup function that throws if local target DNS is attempted. The managed fetch returned a successful 200 response with zero local lookup calls.</p><p>Additional proof showed the proxy allowing a public destination while denying loopback, private, and link-local targets after proxy-side DNS resolution.</p><h2>Bottom Line</h2><p>PR #98951 fixes a real operational mismatch between strict guarded fetch and managed proxy-only networking.</p><p>For operators using OpenClaw behind a managed proxy, fetches can now reach the enforcement boundary that is supposed to make the decision, without falling over on local DNS first.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-managed-proxy-guarded-fetch.png\" alt=\"OpenClaw Fixes Managed Proxy Guarded Fetch\" /></p>",
      "date_published": "2026-07-02T23:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Fixes",
        "Managed",
        "Proxy",
        "Guarded",
        "Fetch"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-managed-proxy-guarded-fetch.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-managed-proxy-guarded-fetch.png",
          "mime_type": "image/png",
          "title": "OpenClaw Fixes Managed Proxy Guarded Fetch cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-android-node-event-queue/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-android-node-event-queue/",
      "title": "OpenClaw Android Queues Node Events Safely",
      "summary": "OpenClaw now queues Android notification node events until Gateway handshakes finish, preserving ordered delivery without duplicate replays.",
      "content_text": "OpenClaw merged [PR #92602, \"fix(android): queue node events until gateway connect\"](https://github.com/openclaw/openclaw/pull/92602) late on July 2nd, closing a P1 message-delivery gap in the Android app.\n\nThe bug sat in a narrow but important window: Android notification forwarding could send a `node.event` while the WebSocket existed but the Gateway handshake had not completed. Because the Gateway expects `connect` to be the first request, notifications generated during startup or reconnect could be missed before the session was actually ready.\n\nFor users who rely on Android as a node surface, that matters. Notification forwarding is often the bridge between the phone and automations running elsewhere. A connection that looks alive but silently drops early events is exactly the kind of failure that makes an agent feel unreliable.\n\n## What Changed\n\nThe fix gives each `GatewaySession.Connection` its own pending RPCs and explicit connection state: connecting, ready, or closed. Outbound RPCs only see a connection after it is ready.\n\nNotification events now sit in one bounded FIFO queue and are released only after the Gateway handshake completes. That gives OpenClaw a simple delivery rule: accept events while disconnected or handshaking, then deliver them in order once the session is ready.\n\nThe PR is also careful about duplicate risk. Events that were definitely not enqueued to OkHttp can be retained, but ambiguous post-enqueue failures are dropped rather than replayed. They still consume their configured rate-limit slot, which keeps retries from becoming a duplicate-delivery path.\n\n## Policy Still Applies\n\nThis is not a blind replay buffer. The Android app rechecks listener access, package policy, quiet hours, and session routing at delivery time.\n\nThat detail is important because reconnect windows can overlap with user changes. If a user tightens notification policy while events are waiting, the outbox should not push stale content that no longer satisfies the current rules.\n\nThe implementation also coordinates notification-policy writes with outbox generation rollover, so restrictive policy changes become visible before another RPC is admitted.\n\n## Why It Matters\n\nThe visible user impact is straightforward: notifications accepted while Android is disconnected or still handshaking should be delivered after reconnect, in order, without a duplicate replay storm.\n\nThat is a stronger contract than simply retrying whatever was active on the phone. The PR body explicitly says it does not replay the device's entire active-notification set after reconnect. Instead, it keeps a bounded queue of accepted events and applies current policy when those events are sent.\n\nFor operators, this makes Android notification forwarding easier to trust during mobile network changes, Gateway restarts, and initial app startup.\n\n## Evidence\n\nThe PR includes a real Gateway proof on an Android 36.1 emulator. The tester stopped the Gateway, waited until the node connection closed, posted a unique shell notification, and restarted the Gateway.\n\nAfter the handshake completed, the Gateway received exactly one `node.event`, returned success in 186 milliseconds, and no duplicate followed.\n\nFocused Android unit suites also passed for gateway invocation, reconnect behavior, notification outbox handling, and bootstrap auth. The change was additionally checked with Android lint, app assembly, native i18n validation, `pnpm check:changed`, and autoreview.\n\n## Bottom Line\n\nPR #92602 turns a timing-sensitive Android transport bug into a bounded, policy-aware queue.\n\nThat is the right shape for a mobile node: no early send before `connect`, no broad notification replay after reconnect, and no duplicate sends when the transport state is ambiguous.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/92602\">PR #92602, \"fix(android): queue node events until gateway connect\"</a> late on July 2nd, closing a P1 message-delivery gap in the Android app.</p><p>The bug sat in a narrow but important window: Android notification forwarding could send a <code>node.event</code> while the WebSocket existed but the Gateway handshake had not completed. Because the Gateway expects <code>connect</code> to be the first request, notifications generated during startup or reconnect could be missed before the session was actually ready.</p><p>For users who rely on Android as a node surface, that matters. Notification forwarding is often the bridge between the phone and automations running elsewhere. A connection that looks alive but silently drops early events is exactly the kind of failure that makes an agent feel unreliable.</p><h2>What Changed</h2><p>The fix gives each <code>GatewaySession.Connection</code> its own pending RPCs and explicit connection state: connecting, ready, or closed. Outbound RPCs only see a connection after it is ready.</p><p>Notification events now sit in one bounded FIFO queue and are released only after the Gateway handshake completes. That gives OpenClaw a simple delivery rule: accept events while disconnected or handshaking, then deliver them in order once the session is ready.</p><p>The PR is also careful about duplicate risk. Events that were definitely not enqueued to OkHttp can be retained, but ambiguous post-enqueue failures are dropped rather than replayed. They still consume their configured rate-limit slot, which keeps retries from becoming a duplicate-delivery path.</p><h2>Policy Still Applies</h2><p>This is not a blind replay buffer. The Android app rechecks listener access, package policy, quiet hours, and session routing at delivery time.</p><p>That detail is important because reconnect windows can overlap with user changes. If a user tightens notification policy while events are waiting, the outbox should not push stale content that no longer satisfies the current rules.</p><p>The implementation also coordinates notification-policy writes with outbox generation rollover, so restrictive policy changes become visible before another RPC is admitted.</p><h2>Why It Matters</h2><p>The visible user impact is straightforward: notifications accepted while Android is disconnected or still handshaking should be delivered after reconnect, in order, without a duplicate replay storm.</p><p>That is a stronger contract than simply retrying whatever was active on the phone. The PR body explicitly says it does not replay the device's entire active-notification set after reconnect. Instead, it keeps a bounded queue of accepted events and applies current policy when those events are sent.</p><p>For operators, this makes Android notification forwarding easier to trust during mobile network changes, Gateway restarts, and initial app startup.</p><h2>Evidence</h2><p>The PR includes a real Gateway proof on an Android 36.1 emulator. The tester stopped the Gateway, waited until the node connection closed, posted a unique shell notification, and restarted the Gateway.</p><p>After the handshake completed, the Gateway received exactly one <code>node.event</code>, returned success in 186 milliseconds, and no duplicate followed.</p><p>Focused Android unit suites also passed for gateway invocation, reconnect behavior, notification outbox handling, and bootstrap auth. The change was additionally checked with Android lint, app assembly, native i18n validation, <code>pnpm check:changed</code>, and autoreview.</p><h2>Bottom Line</h2><p>PR #92602 turns a timing-sensitive Android transport bug into a bounded, policy-aware queue.</p><p>That is the right shape for a mobile node: no early send before <code>connect</code>, no broad notification replay after reconnect, and no duplicate sends when the transport state is ambiguous.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-android-node-event-queue.png\" alt=\"OpenClaw Android Queues Node Events Safely\" /></p>",
      "date_published": "2026-07-02T23:01:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Android",
        "Queues",
        "Node",
        "Events",
        "Safely"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-android-node-event-queue.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-android-node-event-queue.png",
          "mime_type": "image/png",
          "title": "OpenClaw Android Queues Node Events Safely cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-ios-chat-clean-composer/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-ios-chat-clean-composer/",
      "title": "OpenClaw iOS Chat Gets a Cleaner Composer",
      "summary": "OpenClaw refined the iOS chat screen with cleaner assistant typography, a compact composer, and tappable Liquid Glass controls.",
      "content_text": "OpenClaw merged [PR #98953, \"feat(ios): refine the chat experience\"](https://github.com/openclaw/openclaw/pull/98953) on July 2nd, continuing the iOS app polish that started landing around the public mobile release.\n\nThis one is a user-interface change, but it is not just visual cleanup. Chat is the primary surface where a mobile user talks to an agent, watches it stream, sees tool activity, and sends follow-up instructions. Small layout mistakes become daily friction.\n\nThe PR body says the previous iOS chat felt \"visually heavy and mechanically assembled\" because of duplicate intro cards, a large status badge, generic assistant containers, and a composer that used more vertical space than necessary.\n\n## What Changed\n\nThe refined chat interface keeps user messages in clear bubbles, but lets assistant content use more open typography. Transient assistant states keep the same geometry, so loading and streaming do not feel like a separate visual system.\n\nThe header also gets quieter. Instead of a large text status badge competing with the agent identity, connection status moves into a compact semantic icon.\n\nThe composer is the other major part of the change. Attachment, text, voice, and send controls now form one adaptive surface on iOS 26 using Liquid Glass, with a material fallback on older systems.\n\nThe composer starts at 44 points tall, grows through four lines as the user types, and preserves 44-point hit regions for attachment, voice, and send. That last detail matters on mobile: a compact UI is only better if it remains easy to tap.\n\n## Why It Matters\n\nOpenClaw's mobile apps are no longer just remote controls for a terminal agent. The public iOS and Android release shifted them toward first-class app surfaces, and the UI now has to carry more responsibility.\n\nFor chat, the central design problem is density. The app needs to show context, message history, agent state, tool activity, and controls without making every response look like a boxed widget.\n\nPR #98953 moves the interface in that direction. Assistant text becomes easier to scan, the idle state stops competing with operational feedback, and the input area takes less space until the user actually needs more room.\n\n## Proof and Accessibility\n\nThe PR includes before-and-after screenshots, compact and expanded composer screenshots, light appearance proof, and a live Gateway round-trip. In that live test, the app paired to an isolated local Gateway, sent a unique marker through a deterministic OpenAI Responses endpoint, rendered the echoed marker, relaunched with paired credentials, and opened Control Overview.\n\nThe validation also includes a UI test asserting that attachment, Talk, and Send each expose at least a 44 by 44 point hittable region.\n\nThat is the right kind of proof for this sort of change. A chat redesign should not just look cleaner in a static screenshot; it needs to preserve pairing, live sending, accessibility, dynamic type expectations, and interaction targets.\n\n## Related Mobile Work\n\nThis PR landed shortly after [PR #98811](https://github.com/openclaw/openclaw/pull/98811), which modernized iOS navigation and settings, and [PR #98736](https://github.com/openclaw/openclaw/pull/98736), which simplified Talk controls and composer alignment.\n\nTogether, these changes show the native app moving away from dense custom panels and toward a more conventional iOS experience: standard navigation, clearer hierarchy, compact controls, and less visual noise around the core agent interaction.\n\n## Bottom Line\n\nOpenClaw's iOS chat screen now feels more like a place to work with an agent and less like a stack of status containers.\n\nThat is a meaningful step for the mobile app. As OpenClaw moves more everyday workflows onto phone surfaces, the chat composer and message presentation need to be fast, quiet, and hard to mis-tap. PR #98953 pushes the app in exactly that direction.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98953\">PR #98953, \"feat(ios): refine the chat experience\"</a> on July 2nd, continuing the iOS app polish that started landing around the public mobile release.</p><p>This one is a user-interface change, but it is not just visual cleanup. Chat is the primary surface where a mobile user talks to an agent, watches it stream, sees tool activity, and sends follow-up instructions. Small layout mistakes become daily friction.</p><p>The PR body says the previous iOS chat felt \"visually heavy and mechanically assembled\" because of duplicate intro cards, a large status badge, generic assistant containers, and a composer that used more vertical space than necessary.</p><h2>What Changed</h2><p>The refined chat interface keeps user messages in clear bubbles, but lets assistant content use more open typography. Transient assistant states keep the same geometry, so loading and streaming do not feel like a separate visual system.</p><p>The header also gets quieter. Instead of a large text status badge competing with the agent identity, connection status moves into a compact semantic icon.</p><p>The composer is the other major part of the change. Attachment, text, voice, and send controls now form one adaptive surface on iOS 26 using Liquid Glass, with a material fallback on older systems.</p><p>The composer starts at 44 points tall, grows through four lines as the user types, and preserves 44-point hit regions for attachment, voice, and send. That last detail matters on mobile: a compact UI is only better if it remains easy to tap.</p><h2>Why It Matters</h2><p>OpenClaw's mobile apps are no longer just remote controls for a terminal agent. The public iOS and Android release shifted them toward first-class app surfaces, and the UI now has to carry more responsibility.</p><p>For chat, the central design problem is density. The app needs to show context, message history, agent state, tool activity, and controls without making every response look like a boxed widget.</p><p>PR #98953 moves the interface in that direction. Assistant text becomes easier to scan, the idle state stops competing with operational feedback, and the input area takes less space until the user actually needs more room.</p><h2>Proof and Accessibility</h2><p>The PR includes before-and-after screenshots, compact and expanded composer screenshots, light appearance proof, and a live Gateway round-trip. In that live test, the app paired to an isolated local Gateway, sent a unique marker through a deterministic OpenAI Responses endpoint, rendered the echoed marker, relaunched with paired credentials, and opened Control Overview.</p><p>The validation also includes a UI test asserting that attachment, Talk, and Send each expose at least a 44 by 44 point hittable region.</p><p>That is the right kind of proof for this sort of change. A chat redesign should not just look cleaner in a static screenshot; it needs to preserve pairing, live sending, accessibility, dynamic type expectations, and interaction targets.</p><h2>Related Mobile Work</h2><p>This PR landed shortly after <a href=\"https://github.com/openclaw/openclaw/pull/98811\">PR #98811</a>, which modernized iOS navigation and settings, and <a href=\"https://github.com/openclaw/openclaw/pull/98736\">PR #98736</a>, which simplified Talk controls and composer alignment.</p><p>Together, these changes show the native app moving away from dense custom panels and toward a more conventional iOS experience: standard navigation, clearer hierarchy, compact controls, and less visual noise around the core agent interaction.</p><h2>Bottom Line</h2><p>OpenClaw's iOS chat screen now feels more like a place to work with an agent and less like a stack of status containers.</p><p>That is a meaningful step for the mobile app. As OpenClaw moves more everyday workflows onto phone surfaces, the chat composer and message presentation need to be fast, quiet, and hard to mis-tap. PR #98953 pushes the app in exactly that direction.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-ios-chat-clean-composer.png\" alt=\"OpenClaw iOS Chat Gets a Cleaner Composer\" /></p>",
      "date_published": "2026-07-02T08:04:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Chat",
        "Gets",
        "Cleaner",
        "Composer"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-ios-chat-clean-composer.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-ios-chat-clean-composer.png",
          "mime_type": "image/png",
          "title": "OpenClaw iOS Chat Gets a Cleaner Composer cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-cron-session-persistence/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-cron-session-persistence/",
      "title": "OpenClaw Restores Persistent Cron Session Targets",
      "summary": "OpenClaw fixed a P1 cron regression so current and session-targeted jobs keep persistent session history unless explicitly isolated.",
      "content_text": "OpenClaw merged [PR #98947, \"fix(cron): restore persistent session targets\"](https://github.com/openclaw/openclaw/pull/98947) on July 2nd, repairing a P1 regression in how scheduled work chooses its session.\n\nThe issue was subtle but important. After the recent detached cron target work, jobs scheduled in `current` or `session:<id>` could unexpectedly run as fresh detached sessions. That meant the cron run no longer had the persistent session history the operator intended it to use.\n\nFor ordinary scheduled reminders, that might look like an odd loss of context. For long-running agent workflows, it could be worse: the job could lose the accumulated conversation state that explained why it was running in the first place.\n\n## What Changed\n\nThe fix restores OpenClaw's clarified product contract: a cron job normally runs in the session it was created from, while an explicitly `isolated` job asks for a detached fresh session.\n\nThat distinction is small in configuration terms, but large in behavior.\n\nThe PR says the broken path affected `current` and `session:<id>` targets by treating every agent-turn cron target as detached. The corrected code keeps the canonical persistence path across target resolution, session identity, storage, prompt caching, run-context tests, and user-facing docs.\n\n## Why It Matters\n\nCron jobs are not just timers in OpenClaw. They can wake agents with context, deliver messages, check systems, resume workflows, or coordinate with other sessions. In that model, the target session is part of the job's identity.\n\nIf a job says \"run in this session,\" the operator expects the next execution to see the same history and assumptions. If the job silently becomes detached, the agent may still wake up, but it wakes up without the state that makes the job meaningful.\n\nThat is why this landed as a P1 fix with session-state, message-delivery, and availability risk labels. The failure mode was not cosmetic. It affected whether scheduled work could continue in the right operational context.\n\n## The Follow-Up Context\n\nThis PR is explicitly a follow-up to [PR #98755](https://github.com/openclaw/openclaw/pull/98755), which added detached session targets for cron runs. That earlier work was useful because operators do need a way to run scheduled jobs away from the source conversation.\n\nThe problem was the default becoming too broad. Detached execution should be available when requested, not imposed on session-targeted jobs that depend on history.\n\nPR #98947 narrows the behavior back to the intended contract: persistent by default for session targets, isolated only when requested.\n\n## Documentation and Tests\n\nThe PR body says the fix updates the cron target-resolution contract and the related docs so the behavior is visible to users. It also calls out deterministic session-state and shared run-context failures that appeared on exact-head CI after the regression.\n\nThat is a useful reminder of how intertwined cron is with the rest of OpenClaw. A scheduling change can touch storage, context, prompts, messages, and channel delivery in one move.\n\n## Bottom Line\n\nThis is the kind of cron fix that operators may not notice if everything goes right, but would absolutely notice if it stayed broken.\n\nOpenClaw now preserves persistent session history for `current` and `session:<id>` cron targets again. Detached cron sessions remain available, but they are back where they belong: behind an explicit isolation choice.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98947\">PR #98947, \"fix(cron): restore persistent session targets\"</a> on July 2nd, repairing a P1 regression in how scheduled work chooses its session.</p><p>The issue was subtle but important. After the recent detached cron target work, jobs scheduled in <code>current</code> or <code>session:<id></code> could unexpectedly run as fresh detached sessions. That meant the cron run no longer had the persistent session history the operator intended it to use.</p><p>For ordinary scheduled reminders, that might look like an odd loss of context. For long-running agent workflows, it could be worse: the job could lose the accumulated conversation state that explained why it was running in the first place.</p><h2>What Changed</h2><p>The fix restores OpenClaw's clarified product contract: a cron job normally runs in the session it was created from, while an explicitly <code>isolated</code> job asks for a detached fresh session.</p><p>That distinction is small in configuration terms, but large in behavior.</p><p>The PR says the broken path affected <code>current</code> and <code>session:<id></code> targets by treating every agent-turn cron target as detached. The corrected code keeps the canonical persistence path across target resolution, session identity, storage, prompt caching, run-context tests, and user-facing docs.</p><h2>Why It Matters</h2><p>Cron jobs are not just timers in OpenClaw. They can wake agents with context, deliver messages, check systems, resume workflows, or coordinate with other sessions. In that model, the target session is part of the job's identity.</p><p>If a job says \"run in this session,\" the operator expects the next execution to see the same history and assumptions. If the job silently becomes detached, the agent may still wake up, but it wakes up without the state that makes the job meaningful.</p><p>That is why this landed as a P1 fix with session-state, message-delivery, and availability risk labels. The failure mode was not cosmetic. It affected whether scheduled work could continue in the right operational context.</p><h2>The Follow-Up Context</h2><p>This PR is explicitly a follow-up to <a href=\"https://github.com/openclaw/openclaw/pull/98755\">PR #98755</a>, which added detached session targets for cron runs. That earlier work was useful because operators do need a way to run scheduled jobs away from the source conversation.</p><p>The problem was the default becoming too broad. Detached execution should be available when requested, not imposed on session-targeted jobs that depend on history.</p><p>PR #98947 narrows the behavior back to the intended contract: persistent by default for session targets, isolated only when requested.</p><h2>Documentation and Tests</h2><p>The PR body says the fix updates the cron target-resolution contract and the related docs so the behavior is visible to users. It also calls out deterministic session-state and shared run-context failures that appeared on exact-head CI after the regression.</p><p>That is a useful reminder of how intertwined cron is with the rest of OpenClaw. A scheduling change can touch storage, context, prompts, messages, and channel delivery in one move.</p><h2>Bottom Line</h2><p>This is the kind of cron fix that operators may not notice if everything goes right, but would absolutely notice if it stayed broken.</p><p>OpenClaw now preserves persistent session history for <code>current</code> and <code>session:<id></code> cron targets again. Detached cron sessions remain available, but they are back where they belong: behind an explicit isolation choice.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-cron-session-persistence.png\" alt=\"OpenClaw Restores Persistent Cron Session Targets\" /></p>",
      "date_published": "2026-07-02T08:02:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Restores",
        "Persistent",
        "Cron",
        "Session",
        "Targets"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-cron-session-persistence.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-cron-session-persistence.png",
          "mime_type": "image/png",
          "title": "OpenClaw Restores Persistent Cron Session Targets cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-2-v2026-7-1-beta1-release/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-2-v2026-7-1-beta1-release/",
      "title": "OpenClaw 2026.7.1 Beta Ships Mobile and Cron Updates",
      "summary": "OpenClaw 2026.7.1-beta.1 adds GPT-5.6 support, external harness attachment, richer mobile apps, and event-driven cron runs.",
      "content_text": "OpenClaw published [v2026.7.1-beta.1](https://github.com/openclaw/openclaw/releases/tag/v2026.7.1-beta.1) on July 2nd, the first July beta after the stable v2026.6.11 line.\n\nThe release is broad, but it has a clear theme: OpenClaw is tightening the paths where users move between models, mobile clients, external coding harnesses, messaging channels, and scheduled automation.\n\nThat makes this beta less about one isolated headline and more about connected operator workflows. A user can select newer OpenAI preview models, attach an external harness to a Gateway session, steer Codex from Telegram, run cron jobs from exit events, and use refreshed native apps with fewer rough edges.\n\n## The Headline Changes\n\nThe release notes call out seven highlights:\n\n- GPT-5.6 family recognition across model catalogs and runtime selection\n- `openclaw attach` for launching an external harness against an existing Gateway session\n- Telegram Codex pairing, steering, and final-reply recovery improvements\n- `on-exit` cron schedules plus detached session-targeted runs\n- Native iOS and Android app refreshes and localization work\n- iMessage poll creation, reading, and voting\n- Scoped conversation capability profiles for future per-conversation boundaries\n\nSeveral of those areas were already visible in late June and early July pull requests, but the beta matters because it bundles them into an installable channel with release evidence and manifests.\n\n## Better Model and Harness Routes\n\nThe model work is led by [PR #98333](https://github.com/openclaw/openclaw/pull/98333), which adds GPT-5.6 Sol, Terra, and Luna support for users with preview access. The release notes also mention Nemotron Super's 1M context window and preservation of explicit OpenRouter authentication headers.\n\nThe harness story comes from [PR #96454](https://github.com/openclaw/openclaw/pull/96454), which added `openclaw attach`. That command mints a temporary Gateway grant, writes a Claude Code MCP config, launches the external harness, and revokes the grant on exit.\n\nTogether, those two changes show where OpenClaw's control-plane work is headed: model selection and external tool access need to be explicit, inspectable, and scoped rather than hidden behind one broad runtime default.\n\n## Cron and Messaging Keep Getting Attention\n\nCron remains one of the busiest parts of OpenClaw. This beta includes the new `on-exit` schedule kind from [PR #92037](https://github.com/openclaw/openclaw/pull/92037), detached session-targeted run work from [PR #98755](https://github.com/openclaw/openclaw/pull/98755), and a set of fixes around timeout model preservation, catch-up deferrals, action-required output, thinking overrides, and daily reset sessions.\n\nMessaging also gets a substantial pass. Telegram reliability fixes cover stalled ingress claims, restart-dropped media, transient polling errors, poison updates, forwarded rich text, plugin callbacks, and rejected rich final replies. iMessage gains poll creation, reading, and voting. Slack, WeChat, Nostr, and other channel paths pick up routing and delivery corrections.\n\nThese are not flashy changes in isolation, but they are exactly the kind of work that determines whether an always-on personal agent feels dependable after weeks of use.\n\n## Native Apps Move Forward\n\nThe release notes describe a native app refresh across iOS and Android. iOS gets newer navigation, settings, Chat, Talk, and onboarding flows, while localization expands across Apple and Android surfaces.\n\nThat matters because OpenClaw's mobile story is now part of the main product, not a side experiment. Earlier docs updates moved the apps out of pre-release language, and this beta continues the shift toward treating mobile as a first-class control surface.\n\n## Validation\n\nThe release includes downloadable evidence artifacts, a release manifest, postpublish evidence, and checksums. The notes also link to the full release CI report, release publish workflow, npm preflight, validation workflow, plugin publishing, and Windows Hub promotion evidence.\n\nFor a beta with this many surfaces, that evidence trail is important. It gives operators more than a changelog: it gives them a way to trace what was built, published, and verified.\n\n## Bottom Line\n\nOpenClaw v2026.7.1-beta.1 is a platform beta. GPT-5.6 support and `openclaw attach` are the most obvious developer-facing changes, but the release is just as much about cron correctness, messaging durability, and native app polish.\n\nIf you run OpenClaw as a personal operating layer rather than a single terminal tool, this is the kind of beta worth watching closely.",
      "content_html": "<p>OpenClaw published <a href=\"https://github.com/openclaw/openclaw/releases/tag/v2026.7.1-beta.1\">v2026.7.1-beta.1</a> on July 2nd, the first July beta after the stable v2026.6.11 line.</p><p>The release is broad, but it has a clear theme: OpenClaw is tightening the paths where users move between models, mobile clients, external coding harnesses, messaging channels, and scheduled automation.</p><p>That makes this beta less about one isolated headline and more about connected operator workflows. A user can select newer OpenAI preview models, attach an external harness to a Gateway session, steer Codex from Telegram, run cron jobs from exit events, and use refreshed native apps with fewer rough edges.</p><h2>The Headline Changes</h2><p>The release notes call out seven highlights:</p><ul><li>GPT-5.6 family recognition across model catalogs and runtime selection</li><li><code>openclaw attach</code> for launching an external harness against an existing Gateway session</li><li>Telegram Codex pairing, steering, and final-reply recovery improvements</li><li><code>on-exit</code> cron schedules plus detached session-targeted runs</li><li>Native iOS and Android app refreshes and localization work</li><li>iMessage poll creation, reading, and voting</li><li>Scoped conversation capability profiles for future per-conversation boundaries</li></ul><p>Several of those areas were already visible in late June and early July pull requests, but the beta matters because it bundles them into an installable channel with release evidence and manifests.</p><h2>Better Model and Harness Routes</h2><p>The model work is led by <a href=\"https://github.com/openclaw/openclaw/pull/98333\">PR #98333</a>, which adds GPT-5.6 Sol, Terra, and Luna support for users with preview access. The release notes also mention Nemotron Super's 1M context window and preservation of explicit OpenRouter authentication headers.</p><p>The harness story comes from <a href=\"https://github.com/openclaw/openclaw/pull/96454\">PR #96454</a>, which added <code>openclaw attach</code>. That command mints a temporary Gateway grant, writes a Claude Code MCP config, launches the external harness, and revokes the grant on exit.</p><p>Together, those two changes show where OpenClaw's control-plane work is headed: model selection and external tool access need to be explicit, inspectable, and scoped rather than hidden behind one broad runtime default.</p><h2>Cron and Messaging Keep Getting Attention</h2><p>Cron remains one of the busiest parts of OpenClaw. This beta includes the new <code>on-exit</code> schedule kind from <a href=\"https://github.com/openclaw/openclaw/pull/92037\">PR #92037</a>, detached session-targeted run work from <a href=\"https://github.com/openclaw/openclaw/pull/98755\">PR #98755</a>, and a set of fixes around timeout model preservation, catch-up deferrals, action-required output, thinking overrides, and daily reset sessions.</p><p>Messaging also gets a substantial pass. Telegram reliability fixes cover stalled ingress claims, restart-dropped media, transient polling errors, poison updates, forwarded rich text, plugin callbacks, and rejected rich final replies. iMessage gains poll creation, reading, and voting. Slack, WeChat, Nostr, and other channel paths pick up routing and delivery corrections.</p><p>These are not flashy changes in isolation, but they are exactly the kind of work that determines whether an always-on personal agent feels dependable after weeks of use.</p><h2>Native Apps Move Forward</h2><p>The release notes describe a native app refresh across iOS and Android. iOS gets newer navigation, settings, Chat, Talk, and onboarding flows, while localization expands across Apple and Android surfaces.</p><p>That matters because OpenClaw's mobile story is now part of the main product, not a side experiment. Earlier docs updates moved the apps out of pre-release language, and this beta continues the shift toward treating mobile as a first-class control surface.</p><h2>Validation</h2><p>The release includes downloadable evidence artifacts, a release manifest, postpublish evidence, and checksums. The notes also link to the full release CI report, release publish workflow, npm preflight, validation workflow, plugin publishing, and Windows Hub promotion evidence.</p><p>For a beta with this many surfaces, that evidence trail is important. It gives operators more than a changelog: it gives them a way to trace what was built, published, and verified.</p><h2>Bottom Line</h2><p>OpenClaw v2026.7.1-beta.1 is a platform beta. GPT-5.6 support and <code>openclaw attach</code> are the most obvious developer-facing changes, but the release is just as much about cron correctness, messaging durability, and native app polish.</p><p>If you run OpenClaw as a personal operating layer rather than a single terminal tool, this is the kind of beta worth watching closely.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-v2026-7-1-beta1-release.png\" alt=\"OpenClaw 2026.7.1 Beta Ships Mobile and Cron Updates\" /></p>",
      "date_published": "2026-07-02T08:00:00.000Z",
      "date_modified": "2026-07-09T08:12:14.647Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "2026",
        "Beta",
        "Ships",
        "Mobile",
        "Cron"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-v2026-7-1-beta1-release.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-2-v2026-7-1-beta1-release.png",
          "mime_type": "image/png",
          "title": "OpenClaw 2026.7.1 Beta Ships Mobile and Cron Updates cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-1-cron-detached-session-targets/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-1-cron-detached-session-targets/",
      "title": "OpenClaw Cron Jobs Stop Polluting Live Sessions",
      "summary": "OpenClaw changed session-targeted cron jobs so scheduled runs execute detached while still delivering results to the chosen source session.",
      "content_text": "OpenClaw merged [PR #98755, \"fix(cron): detach session-targeted runs\"](https://github.com/openclaw/openclaw/pull/98755) on July 1st, tightening a subtle but important boundary between scheduled work and live conversations.\n\nThe fix targets `current` and `session:<id>` cron jobs. These jobs were using the source chat or session key as the execution session, which meant scheduled work could block or contaminate the same transcript a human was actively using.\n\nThat is a small implementation detail with a very visible operator impact.\n\n## What Changed\n\nThe PR changes `isolated`, `current`, and `session:<id>` cron jobs to run as detached execution targets. The selected source session is still used for delivery, but the actual scheduled work gets its own execution context.\n\nThat split lets OpenClaw preserve the intent of session-targeted cron: send results back to the relevant chat, topic, or transcript. At the same time, it keeps the scheduled agent turn from becoming part of the live interaction lane.\n\nThe PR body also mentions cleanup around task rows that could otherwise be left in awkward childless or no-handle states.\n\n## Why This Matters\n\nCron jobs are one of the places where OpenClaw becomes a long-running operations system. A job can wake an agent, run checks, summarize state, execute maintenance, or monitor external services while the user is elsewhere.\n\nThose jobs still need to report to the right place. But they should not take over the same session state that a user may be steering in real time.\n\nWhen scheduled work shares the live transcript too directly, several things can go wrong:\n\n- A cron run can block the chat lane while the user is trying to interact\n- Scheduled output can alter the context of the live conversation\n- Task bookkeeping can become harder to reason about\n- Recovery after a failed or interrupted run can leave confusing session artifacts\n\nDetached execution is the cleaner model: run the job separately, then deliver the result to the selected source.\n\n## A Stronger Automation Boundary\n\nThis also fits the direction OpenClaw has been taking over the last several releases. Cron delivery, target awareness, action-required output preservation, and session wake behavior have all been getting more explicit.\n\nPR #98755 continues that trend by separating where a job runs from where its result lands.\n\nThat distinction matters for reliability, but it also matters for trust. Operators should be able to schedule work against a conversation without worrying that the job will silently reshape the active transcript or compete with a human turn.\n\n## Validation\n\nThe PR is labeled P1 and includes Telegram-visible proof tags, which is the right test surface for this class of bug. The failure is not just internal bookkeeping; it affects how scheduled work appears in real channel sessions.\n\nThe reported change focuses on source-session delivery, detached execution targeting, and related task-state behavior. That makes the fix narrow enough to reason about while addressing the operational symptom.\n\n## Bottom Line\n\nOpenClaw cron jobs now have a sharper execution boundary for session-targeted work.\n\nScheduled jobs can still report back to the conversation they are meant to serve, but they no longer have to run inside the live session they are reporting to. For operators who use cron as an automation layer, that is a cleaner and safer default.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/98755\">PR #98755, \"fix(cron): detach session-targeted runs\"</a> on July 1st, tightening a subtle but important boundary between scheduled work and live conversations.</p><p>The fix targets <code>current</code> and <code>session:<id></code> cron jobs. These jobs were using the source chat or session key as the execution session, which meant scheduled work could block or contaminate the same transcript a human was actively using.</p><p>That is a small implementation detail with a very visible operator impact.</p><h2>What Changed</h2><p>The PR changes <code>isolated</code>, <code>current</code>, and <code>session:<id></code> cron jobs to run as detached execution targets. The selected source session is still used for delivery, but the actual scheduled work gets its own execution context.</p><p>That split lets OpenClaw preserve the intent of session-targeted cron: send results back to the relevant chat, topic, or transcript. At the same time, it keeps the scheduled agent turn from becoming part of the live interaction lane.</p><p>The PR body also mentions cleanup around task rows that could otherwise be left in awkward childless or no-handle states.</p><h2>Why This Matters</h2><p>Cron jobs are one of the places where OpenClaw becomes a long-running operations system. A job can wake an agent, run checks, summarize state, execute maintenance, or monitor external services while the user is elsewhere.</p><p>Those jobs still need to report to the right place. But they should not take over the same session state that a user may be steering in real time.</p><p>When scheduled work shares the live transcript too directly, several things can go wrong:</p><ul><li>A cron run can block the chat lane while the user is trying to interact</li><li>Scheduled output can alter the context of the live conversation</li><li>Task bookkeeping can become harder to reason about</li><li>Recovery after a failed or interrupted run can leave confusing session artifacts</li></ul><p>Detached execution is the cleaner model: run the job separately, then deliver the result to the selected source.</p><h2>A Stronger Automation Boundary</h2><p>This also fits the direction OpenClaw has been taking over the last several releases. Cron delivery, target awareness, action-required output preservation, and session wake behavior have all been getting more explicit.</p><p>PR #98755 continues that trend by separating where a job runs from where its result lands.</p><p>That distinction matters for reliability, but it also matters for trust. Operators should be able to schedule work against a conversation without worrying that the job will silently reshape the active transcript or compete with a human turn.</p><h2>Validation</h2><p>The PR is labeled P1 and includes Telegram-visible proof tags, which is the right test surface for this class of bug. The failure is not just internal bookkeeping; it affects how scheduled work appears in real channel sessions.</p><p>The reported change focuses on source-session delivery, detached execution targeting, and related task-state behavior. That makes the fix narrow enough to reason about while addressing the operational symptom.</p><h2>Bottom Line</h2><p>OpenClaw cron jobs now have a sharper execution boundary for session-targeted work.</p><p>Scheduled jobs can still report back to the conversation they are meant to serve, but they no longer have to run inside the live session they are reporting to. For operators who use cron as an automation layer, that is a cleaner and safer default.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-detached-session-targets.png\" alt=\"OpenClaw Cron Jobs Stop Polluting Live Sessions\" /></p>",
      "date_published": "2026-07-01T23:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "Releases",
        "Cron",
        "Jobs",
        "Stop",
        "Polluting",
        "Live"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-detached-session-targets.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-detached-session-targets.png",
          "mime_type": "image/png",
          "title": "OpenClaw Cron Jobs Stop Polluting Live Sessions cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-1-telegram-poison-message-recovery/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-1-telegram-poison-message-recovery/",
      "title": "OpenClaw Telegram Queues Recover From Poison Messages",
      "summary": "OpenClaw fixed Telegram spool retries so poison updates back off, dead-letter, and stop blocking later chat messages.",
      "content_text": "OpenClaw merged a late July 1st Telegram reliability cluster, led by [PR #98776](https://github.com/openclaw/openclaw/pull/98776) and [PR #98775](https://github.com/openclaw/openclaw/pull/98775), that tightens how the Telegram channel handles failed polling, spooled updates, duplicate delivery, and stuck queue lanes.\n\nThe user-facing result is straightforward: a single bad Telegram update should no longer freeze an entire chat or topic.\n\n## What Broke\n\nPR #98776 describes a spool failure mode where one Telegram update could keep retrying every roughly 500ms forever. Because the spool drain claims the lowest update ID per conversation lane, that poison row could permanently block later messages in the same chat or topic.\n\nThe same PR also fixes two related defects:\n\n- A transient store read error during restart replay could silently delete a spooled message\n- Successfully processed rows were deleted instead of tombstoned, so crash-window refetches could re-dispatch already processed updates\n\nThat last case is especially important for callback queries and buttons. A duplicate delivery is not just noisy; it can repeat a side effect.\n\n## The Recovery Model\n\nPR #98776 generalizes Telegram spool backoff across retryable failures. Failed spooled updates now back off exponentially from persisted queue state, starting at a one-second base and capping at three minutes.\n\nAfter eight attempts, the stuck row dead-letters to the existing failed tombstones. That means the lane can move forward instead of being held hostage by one malformed or persistently failing update.\n\nThe success path now uses completed tombstones with retention, so enqueue-time duplicate detection can absorb refetched updates after a crash window. The PR also fixes redrain ordering so lane guards clear before immediate redrain is requested.\n\n## Polling Gets Safer Too\n\nThe sibling [PR #98775](https://github.com/openclaw/openclaw/pull/98775) addresses Telegram polling itself. It fixes transient `getUpdates` failures, including rate limits and server errors, so they do not crash the account polling session and eventually disable the channel through repeated supervisor restarts.\n\nThat PR also stops per-send cache rewrites on the hot path, reducing the amount of state churn around Telegram delivery.\n\nTaken together, the two PRs improve both ends of the same channel path: receiving updates from Telegram and replaying them durably through OpenClaw.\n\n## Why Operators Should Care\n\nTelegram is often used as a primary control surface for OpenClaw. It is where users send commands, steer active runs, approve actions, and receive results.\n\nWhen a channel lane freezes, the symptom is ugly: later messages appear to vanish, command recovery gets delayed, and operators may restart the Gateway without knowing which update caused the jam.\n\nThe new behavior gives the system a better failure shape. Retryable failures back off. Persistent failures dead-letter. Later messages can proceed. Duplicate refetches are filtered instead of replayed.\n\n## Validation\n\nThe PRs report focused regression coverage for dead-lettering after max attempts, transient pairing-store replay errors, completed-then-refetched duplicate detection, polling session behavior, and combined merge validation across sibling Telegram fixes.\n\nThe important proof is not just that the channel survives one happy path. It is that Telegram can now handle poison updates, transient API failures, restart windows, and duplicate refetches without turning one failed row into a stuck conversation.\n\n## Bottom Line\n\nOpenClaw's Telegram channel is getting a more durable queue discipline.\n\nFor anyone running OpenClaw through Telegram, this is the kind of boring infrastructure fix that matters: failed messages are contained, later messages keep moving, and restart windows should be less likely to lose or repeat work.",
      "content_html": "<p>OpenClaw merged a late July 1st Telegram reliability cluster, led by <a href=\"https://github.com/openclaw/openclaw/pull/98776\">PR #98776</a> and <a href=\"https://github.com/openclaw/openclaw/pull/98775\">PR #98775</a>, that tightens how the Telegram channel handles failed polling, spooled updates, duplicate delivery, and stuck queue lanes.</p><p>The user-facing result is straightforward: a single bad Telegram update should no longer freeze an entire chat or topic.</p><h2>What Broke</h2><p>PR #98776 describes a spool failure mode where one Telegram update could keep retrying every roughly 500ms forever. Because the spool drain claims the lowest update ID per conversation lane, that poison row could permanently block later messages in the same chat or topic.</p><p>The same PR also fixes two related defects:</p><ul><li>A transient store read error during restart replay could silently delete a spooled message</li><li>Successfully processed rows were deleted instead of tombstoned, so crash-window refetches could re-dispatch already processed updates</li></ul><p>That last case is especially important for callback queries and buttons. A duplicate delivery is not just noisy; it can repeat a side effect.</p><h2>The Recovery Model</h2><p>PR #98776 generalizes Telegram spool backoff across retryable failures. Failed spooled updates now back off exponentially from persisted queue state, starting at a one-second base and capping at three minutes.</p><p>After eight attempts, the stuck row dead-letters to the existing failed tombstones. That means the lane can move forward instead of being held hostage by one malformed or persistently failing update.</p><p>The success path now uses completed tombstones with retention, so enqueue-time duplicate detection can absorb refetched updates after a crash window. The PR also fixes redrain ordering so lane guards clear before immediate redrain is requested.</p><h2>Polling Gets Safer Too</h2><p>The sibling <a href=\"https://github.com/openclaw/openclaw/pull/98775\">PR #98775</a> addresses Telegram polling itself. It fixes transient <code>getUpdates</code> failures, including rate limits and server errors, so they do not crash the account polling session and eventually disable the channel through repeated supervisor restarts.</p><p>That PR also stops per-send cache rewrites on the hot path, reducing the amount of state churn around Telegram delivery.</p><p>Taken together, the two PRs improve both ends of the same channel path: receiving updates from Telegram and replaying them durably through OpenClaw.</p><h2>Why Operators Should Care</h2><p>Telegram is often used as a primary control surface for OpenClaw. It is where users send commands, steer active runs, approve actions, and receive results.</p><p>When a channel lane freezes, the symptom is ugly: later messages appear to vanish, command recovery gets delayed, and operators may restart the Gateway without knowing which update caused the jam.</p><p>The new behavior gives the system a better failure shape. Retryable failures back off. Persistent failures dead-letter. Later messages can proceed. Duplicate refetches are filtered instead of replayed.</p><h2>Validation</h2><p>The PRs report focused regression coverage for dead-lettering after max attempts, transient pairing-store replay errors, completed-then-refetched duplicate detection, polling session behavior, and combined merge validation across sibling Telegram fixes.</p><p>The important proof is not just that the channel survives one happy path. It is that Telegram can now handle poison updates, transient API failures, restart windows, and duplicate refetches without turning one failed row into a stuck conversation.</p><h2>Bottom Line</h2><p>OpenClaw's Telegram channel is getting a more durable queue discipline.</p><p>For anyone running OpenClaw through Telegram, this is the kind of boring infrastructure fix that matters: failed messages are contained, later messages keep moving, and restart windows should be less likely to lose or repeat work.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-telegram-poison-message-recovery.png\" alt=\"OpenClaw Telegram Queues Recover From Poison Messages\" /></p>",
      "date_published": "2026-07-01T23:05:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Telegram",
        "Queues",
        "Recover",
        "Poison",
        "Messages"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-telegram-poison-message-recovery.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-telegram-poison-message-recovery.png",
          "mime_type": "image/png",
          "title": "OpenClaw Telegram Queues Recover From Poison Messages cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-1-attach-claude-code/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-1-attach-claude-code/",
      "title": "OpenClaw Attach Brings Claude Code Into Sessions",
      "summary": "OpenClaw added an attach command that launches Claude Code with scoped Gateway MCP access and revokes the temporary grant on exit.",
      "content_text": "OpenClaw merged [PR #96454, \"feat(cli): openclaw attach - launch an external harness bound to a gateway session\"](https://github.com/openclaw/openclaw/pull/96454) late on July 1st, turning the lower-level attach grant work into a user-facing CLI command.\n\nThe new command is designed for a specific operator need: let Claude Code reach OpenClaw Gateway MCP tools for one Gateway session without handing it a durable, process-global credential.\n\nThat matters because external harnesses are useful, but they are also a boundary. If operators have to mint a token by hand, write an MCP config by hand, and remember to revoke the grant later, the path is easy to get wrong.\n\n## What Changed\n\nThe new surface is `openclaw attach`. According to the PR, it mints a per-session attach grant through the Gateway, writes a temporary `.mcp.json` for Claude Code, launches Claude with `--strict-mcp-config --mcp-config <path>`, and revokes the grant when the child process exits.\n\nThe command includes options for the common cases:\n\n- `--session <key>` binds the grant to a specific Gateway session\n- `--ttl <ms>` requests a bounded grant lifetime\n- `--bin <path>` chooses the Claude Code binary\n- `--print-config` writes the config and prints launch details without spawning Claude\n\nThe PR also adds docs at `docs/cli/attach.md` and registers the command in the CLI catalog, so it is not just a hidden gateway primitive.\n\n## Why It Matters\n\nThis is a meaningful OpenClaw integration story because it narrows the gap between a personal agent gateway and a dedicated coding harness.\n\nBefore this command, a user who wanted Claude Code to use OpenClaw Gateway tools would have needed to assemble the grant, environment, headers, and config manually. PR #96454 makes that flow explicit and repeatable.\n\nThe security design is the important part. The bearer token rides through environment variables, not argv. The temporary config is scoped to the attach flow. The Gateway grant is session-bound, TTL-bounded, and revoked on normal exit.\n\nThat gives operators a clean way to let Claude Code act inside an OpenClaw session without permanently broadening every MCP server or every OpenClaw tool path around it.\n\n## Boundary Fixes Included\n\nThe PR body calls out a live-gateway proof that caught a real auth bug. The command originally used a backend-style gateway mode that dropped the operator device identity, causing `attach.grant` to fail with a missing `operator.admin` scope.\n\nThe final version calls the Gateway in CLI mode so the operator identity is resolved correctly. Tests now guard that behavior.\n\nThe patch also switches attach configs to token-only headers. That keeps the attach MCP config from depending on session-context placeholders that Claude Code would not supply.\n\n## Validation\n\nThe PR reports both unit and live behavior proof. Tests cover config writing and cleanup, `--print-config`, TTL validation, malformed grant responses, spawn exit handling, error handling, revoke-once behavior, and signal listener cleanup.\n\nThe live proof built OpenClaw in an isolated Linux container, ran a headless Gateway, minted a real attach grant, emitted a real `.mcp.json`, launched a harness with the grant, and revoked it on exit.\n\n## Bottom Line\n\n`openclaw attach` is an operator-quality bridge between OpenClaw sessions and Claude Code.\n\nIt gives external harnesses a narrow door into Gateway tools: session-bound, temporary, documented, and revoked. That is the right shape for integrations that need real power without turning every coding tool into a standing all-access client.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/96454\">PR #96454, \"feat(cli): openclaw attach - launch an external harness bound to a gateway session\"</a> late on July 1st, turning the lower-level attach grant work into a user-facing CLI command.</p><p>The new command is designed for a specific operator need: let Claude Code reach OpenClaw Gateway MCP tools for one Gateway session without handing it a durable, process-global credential.</p><p>That matters because external harnesses are useful, but they are also a boundary. If operators have to mint a token by hand, write an MCP config by hand, and remember to revoke the grant later, the path is easy to get wrong.</p><h2>What Changed</h2><p>The new surface is <code>openclaw attach</code>. According to the PR, it mints a per-session attach grant through the Gateway, writes a temporary <code>.mcp.json</code> for Claude Code, launches Claude with <code>--strict-mcp-config --mcp-config <path></code>, and revokes the grant when the child process exits.</p><p>The command includes options for the common cases:</p><ul><li><code>--session <key></code> binds the grant to a specific Gateway session</li><li><code>--ttl <ms></code> requests a bounded grant lifetime</li><li><code>--bin <path></code> chooses the Claude Code binary</li><li><code>--print-config</code> writes the config and prints launch details without spawning Claude</li></ul><p>The PR also adds docs at <code>docs/cli/attach.md</code> and registers the command in the CLI catalog, so it is not just a hidden gateway primitive.</p><h2>Why It Matters</h2><p>This is a meaningful OpenClaw integration story because it narrows the gap between a personal agent gateway and a dedicated coding harness.</p><p>Before this command, a user who wanted Claude Code to use OpenClaw Gateway tools would have needed to assemble the grant, environment, headers, and config manually. PR #96454 makes that flow explicit and repeatable.</p><p>The security design is the important part. The bearer token rides through environment variables, not argv. The temporary config is scoped to the attach flow. The Gateway grant is session-bound, TTL-bounded, and revoked on normal exit.</p><p>That gives operators a clean way to let Claude Code act inside an OpenClaw session without permanently broadening every MCP server or every OpenClaw tool path around it.</p><h2>Boundary Fixes Included</h2><p>The PR body calls out a live-gateway proof that caught a real auth bug. The command originally used a backend-style gateway mode that dropped the operator device identity, causing <code>attach.grant</code> to fail with a missing <code>operator.admin</code> scope.</p><p>The final version calls the Gateway in CLI mode so the operator identity is resolved correctly. Tests now guard that behavior.</p><p>The patch also switches attach configs to token-only headers. That keeps the attach MCP config from depending on session-context placeholders that Claude Code would not supply.</p><h2>Validation</h2><p>The PR reports both unit and live behavior proof. Tests cover config writing and cleanup, <code>--print-config</code>, TTL validation, malformed grant responses, spawn exit handling, error handling, revoke-once behavior, and signal listener cleanup.</p><p>The live proof built OpenClaw in an isolated Linux container, ran a headless Gateway, minted a real attach grant, emitted a real <code>.mcp.json</code>, launched a harness with the grant, and revoked it on exit.</p><h2>Bottom Line</h2><p><code>openclaw attach</code> is an operator-quality bridge between OpenClaw sessions and Claude Code.</p><p>It gives external harnesses a narrow door into Gateway tools: session-bound, temporary, documented, and revoked. That is the right shape for integrations that need real power without turning every coding tool into a standing all-access client.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-attach-claude-code.png\" alt=\"OpenClaw Attach Brings Claude Code Into Sessions\" /></p>",
      "date_published": "2026-07-01T23:00:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Attach",
        "Brings",
        "Claude",
        "Code",
        "Sessions"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-attach-claude-code.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-attach-claude-code.png",
          "mime_type": "image/png",
          "title": "OpenClaw Attach Brings Claude Code Into Sessions cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-1-cron-action-required-output/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-1-cron-action-required-output/",
      "title": "OpenClaw Cron Keeps Action Lines Visible",
      "summary": "OpenClaw fixed cron command jobs so login URLs, setup codes, and other action-required lines survive noisy output truncation.",
      "content_text": "OpenClaw merged [PR #96393, \"fix(cron): preserve action-required command output\"](https://github.com/openclaw/openclaw/pull/96393) on July 1st, fixing a P1 cron reliability bug for command jobs that print the important line early and noisy logs later.\n\nThe bug is familiar to anyone who has run setup or device-login commands from automation. A command prints the URL, code, or next action near the start. Then it emits enough extra output to exceed the configured capture size. The final summary keeps only the tail, and the one line the operator needs is gone.\n\nFor OpenClaw cron jobs, that meant the run summary, run log, announce delivery, and completion webhook could lose the action-required line.\n\n## What Changed\n\nThe fix adds an opt-in output preservation hook to `runCommandWithTimeout()`. Default exec capture behavior stays unchanged. Cron command jobs use the hook to preserve action-required lines even when `outputMaxBytes` keeps only the final tail of stdout and stderr.\n\nCron command summaries now get an `action-required output preserved:` block before the bounded captured tail. That gives operators a better recovery path without removing the existing truncation controls.\n\nThe PR keeps the scope narrow:\n\n- Cron command jobs can preserve action-required lines\n- Ordinary exec and tool calls keep the old tail-bound behavior unless they explicitly opt in\n- Non-command cron summaries are unchanged\n- Captured output and partial-line scanning remain bounded\n\n## Security Boundary\n\nThe security side of this patch is just as important as the preservation behavior. Action-required lines can contain setup URLs, auth codes, device codes, tokens, or password-like assignments.\n\nOpenClaw now keeps those lines where the operator needs them, but redacts them before external delivery. The PR says cron announce delivery, successful completion webhook payloads, completion webhook diagnostics entries, and `cron_changed` hook summaries use redacted command summaries.\n\nFailed completion webhook payloads keep the stricter boundary: they omit `summary`, `diagnostics`, `job.state.lastDiagnosticSummary`, and `job.state.lastDiagnostics`.\n\nThat split is sensible. The operator-facing cron history needs enough detail to recover from a setup flow. External notifications should not spray raw login material into every downstream integration.\n\n## Why This Matters for Operators\n\nCron is one of the places where OpenClaw becomes infrastructure rather than a chat assistant. Jobs may wake a session, check a service, refresh a login, call a deployment command, or run a maintenance task while the operator is away.\n\nWhen those jobs need human action, the summary has to carry the actual instruction. Losing the first `Visit this URL and enter this code` line because a command later printed verbose logs turns automation into a scavenger hunt.\n\nPR #96393 makes that failure mode much less likely while preserving the existing bounded-output model.\n\n## Validation\n\nThe PR includes focused coverage across cron, process execution, gateway notifications, and hook delivery.\n\nThe reported real-behavior proof ran an actual cron command job with an early device-login-style line, a numeric verification code, a token assignment, and noisy tail output. It verified that the operator summary preserved the action line while the external delivery projection redacted the URL, raw code, and token value.\n\nThe proof log reports 91 focused tests passing across gateway, cron, and process shards. Additional tests cover preserved lines surviving tail truncation, long no-newline output staying bounded, summary prepending, URL/code/token redaction, successful webhook payload redaction, failed webhook omission behavior, and redacted `cron_changed` hook summaries.\n\n## Bottom Line\n\nOpenClaw cron command jobs now treat \"what the operator must do next\" as a first-class output class.\n\nThe fix does not simply keep more logs. It preserves actionable lines, keeps noisy tails bounded, and redacts sensitive setup material before external delivery. That is a practical improvement for unattended jobs, device login flows, setup tasks, and any cron automation where the useful instruction appears before the noise.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/96393\">PR #96393, \"fix(cron): preserve action-required command output\"</a> on July 1st, fixing a P1 cron reliability bug for command jobs that print the important line early and noisy logs later.</p><p>The bug is familiar to anyone who has run setup or device-login commands from automation. A command prints the URL, code, or next action near the start. Then it emits enough extra output to exceed the configured capture size. The final summary keeps only the tail, and the one line the operator needs is gone.</p><p>For OpenClaw cron jobs, that meant the run summary, run log, announce delivery, and completion webhook could lose the action-required line.</p><h2>What Changed</h2><p>The fix adds an opt-in output preservation hook to <code>runCommandWithTimeout()</code>. Default exec capture behavior stays unchanged. Cron command jobs use the hook to preserve action-required lines even when <code>outputMaxBytes</code> keeps only the final tail of stdout and stderr.</p><p>Cron command summaries now get an <code>action-required output preserved:</code> block before the bounded captured tail. That gives operators a better recovery path without removing the existing truncation controls.</p><p>The PR keeps the scope narrow:</p><ul><li>Cron command jobs can preserve action-required lines</li><li>Ordinary exec and tool calls keep the old tail-bound behavior unless they explicitly opt in</li><li>Non-command cron summaries are unchanged</li><li>Captured output and partial-line scanning remain bounded</li></ul><h2>Security Boundary</h2><p>The security side of this patch is just as important as the preservation behavior. Action-required lines can contain setup URLs, auth codes, device codes, tokens, or password-like assignments.</p><p>OpenClaw now keeps those lines where the operator needs them, but redacts them before external delivery. The PR says cron announce delivery, successful completion webhook payloads, completion webhook diagnostics entries, and <code>cron_changed</code> hook summaries use redacted command summaries.</p><p>Failed completion webhook payloads keep the stricter boundary: they omit <code>summary</code>, <code>diagnostics</code>, <code>job.state.lastDiagnosticSummary</code>, and <code>job.state.lastDiagnostics</code>.</p><p>That split is sensible. The operator-facing cron history needs enough detail to recover from a setup flow. External notifications should not spray raw login material into every downstream integration.</p><h2>Why This Matters for Operators</h2><p>Cron is one of the places where OpenClaw becomes infrastructure rather than a chat assistant. Jobs may wake a session, check a service, refresh a login, call a deployment command, or run a maintenance task while the operator is away.</p><p>When those jobs need human action, the summary has to carry the actual instruction. Losing the first <code>Visit this URL and enter this code</code> line because a command later printed verbose logs turns automation into a scavenger hunt.</p><p>PR #96393 makes that failure mode much less likely while preserving the existing bounded-output model.</p><h2>Validation</h2><p>The PR includes focused coverage across cron, process execution, gateway notifications, and hook delivery.</p><p>The reported real-behavior proof ran an actual cron command job with an early device-login-style line, a numeric verification code, a token assignment, and noisy tail output. It verified that the operator summary preserved the action line while the external delivery projection redacted the URL, raw code, and token value.</p><p>The proof log reports 91 focused tests passing across gateway, cron, and process shards. Additional tests cover preserved lines surviving tail truncation, long no-newline output staying bounded, summary prepending, URL/code/token redaction, successful webhook payload redaction, failed webhook omission behavior, and redacted <code>cron_changed</code> hook summaries.</p><h2>Bottom Line</h2><p>OpenClaw cron command jobs now treat \"what the operator must do next\" as a first-class output class.</p><p>The fix does not simply keep more logs. It preserves actionable lines, keeps noisy tails bounded, and redacts sensitive setup material before external delivery. That is a practical improvement for unattended jobs, device login flows, setup tasks, and any cron automation where the useful instruction appears before the noise.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-action-required-output.png\" alt=\"OpenClaw Cron Keeps Action Lines Visible\" /></p>",
      "date_published": "2026-07-01T08:15:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Cron",
        "Keeps",
        "Action",
        "Lines",
        "Visible"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-action-required-output.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-cron-action-required-output.png",
          "mime_type": "image/png",
          "title": "OpenClaw Cron Keeps Action Lines Visible cover image"
        }
      ]
    },
    {
      "id": "https://openclawchronicles.com/posts/openclaw-2026-7-1-structured-tool-result-replay/",
      "url": "https://openclawchronicles.com/posts/openclaw-2026-7-1-structured-tool-result-replay/",
      "title": "OpenClaw Preserves Structured Tool Results",
      "summary": "OpenClaw fixed provider replay so structured tool output stays readable instead of collapsing into empty or misleading media placeholders.",
      "content_text": "OpenClaw merged [PR #97742, \"fix(llm): preserve structured tool result text across providers\"](https://github.com/openclaw/openclaw/pull/97742) on July 1st, closing a P1 provider-replay bug that could make structured tool output disappear or look like the wrong kind of attachment.\n\nThe issue is subtle but important. OpenClaw tools do not always return plain text. They may return structured JSON-like blocks, resource metadata, media references, or mixed content. When those results are replayed back through a model provider, the conversion layer has to preserve the useful text without leaking secrets or pretending that structured data is an image.\n\nBefore this fix, structured non-media content could collapse into placeholders such as `(see attached image)`, `(see attached media)`, or even empty output. That loses context and can mislead the model on the next turn.\n\n## The User-Facing Bug\n\nThe PR body names the canonical problem as [issue #96857](https://github.com/openclaw/openclaw/issues/96857). The most visible symptom is that tool output with structured content could be replayed without its actual useful data.\n\nThat matters in practical workflows:\n\n- A JSON resource result can be reduced to a generic media placeholder\n- An audio-only result can be labeled like an image\n- Structured-only output can become empty provider-bound text\n- Follow-up model turns can make decisions without the data a tool actually returned\n\nFor an agent system, that is more than formatting polish. Tool output is part of the reasoning record. If provider replay drops or mislabels it, the model can answer confidently from a distorted transcript.\n\n## What the Fix Does\n\nThe PR preserves explicit text first, then serializes structured non-media blocks as redacted JSON text. Media-only results still use placeholders, but the placeholders are now type-aware:\n\n- image-only results become `(see attached image)`\n- audio-only results become `(see attached audio)`\n- mixed image and audio results become `(see attached media)`\n\nThe patch also redacts or omits risky fields before replay. The PR explicitly calls out secret-like fields, inline data URIs, opaque encrypted fields, and binary `data` fields.\n\nThat is the right balance: preserve useful structured context, but do not turn provider replay into a raw data exfiltration path.\n\n## Provider Coverage Is Broad\n\nThis is not a one-provider patch. The implementation touches shared provider-side extraction and replay paths across OpenAI Responses, OpenAI Completions, Anthropic, Google shared provider handling, Mistral, OpenAI transport streams, and Anthropic transport streams.\n\nThe follow-up repair also closes a sibling gap in the bundled Google extension transport. The PR says `extensions/google/transport-stream.ts` still built `functionResponse.response.output` from explicit text or a media placeholder, so structured-only non-media results could still become empty output. The merged version gives Google transport the same structured replay behavior while keeping the helper boundary inside the private plugin SDK path.\n\nThat boundary detail matters for extension authors. The public Plugin SDK surface did not expand just to solve this internal replay issue.\n\n## Validation\n\nThe regression coverage is targeted and detailed. The PR reports tests for explicit-text precedence, structured JSON serialization, media-only omission from text extraction, image/audio/mixed placeholder selection, inline data URI and binary-field redaction, OpenAI replay behavior, Anthropic transport behavior, Google function response output, xAI audio fallback handling, and plugin SDK alias boundaries.\n\nIt also reports `plugin-sdk:surface:check`, extension package-boundary compilation across 116 bundled extension packages, focused Vitest shards, linting, and `git diff --check`.\n\n## Bottom Line\n\nThis is a reliability and safety fix for OpenClaw's tool transcript layer.\n\nThe important outcome is simple: if a tool returns structured, non-media information, OpenClaw should keep that information readable for the next model turn. If the tool returns media, OpenClaw should describe the media accurately. If the tool returns secrets or opaque binary fields, OpenClaw should not replay them raw.\n\nPR #97742 moves provider replay closer to that standard across the main OpenClaw provider stack.",
      "content_html": "<p>OpenClaw merged <a href=\"https://github.com/openclaw/openclaw/pull/97742\">PR #97742, \"fix(llm): preserve structured tool result text across providers\"</a> on July 1st, closing a P1 provider-replay bug that could make structured tool output disappear or look like the wrong kind of attachment.</p><p>The issue is subtle but important. OpenClaw tools do not always return plain text. They may return structured JSON-like blocks, resource metadata, media references, or mixed content. When those results are replayed back through a model provider, the conversion layer has to preserve the useful text without leaking secrets or pretending that structured data is an image.</p><p>Before this fix, structured non-media content could collapse into placeholders such as <code>(see attached image)</code>, <code>(see attached media)</code>, or even empty output. That loses context and can mislead the model on the next turn.</p><h2>The User-Facing Bug</h2><p>The PR body names the canonical problem as <a href=\"https://github.com/openclaw/openclaw/issues/96857\">issue #96857</a>. The most visible symptom is that tool output with structured content could be replayed without its actual useful data.</p><p>That matters in practical workflows:</p><ul><li>A JSON resource result can be reduced to a generic media placeholder</li><li>An audio-only result can be labeled like an image</li><li>Structured-only output can become empty provider-bound text</li><li>Follow-up model turns can make decisions without the data a tool actually returned</li></ul><p>For an agent system, that is more than formatting polish. Tool output is part of the reasoning record. If provider replay drops or mislabels it, the model can answer confidently from a distorted transcript.</p><h2>What the Fix Does</h2><p>The PR preserves explicit text first, then serializes structured non-media blocks as redacted JSON text. Media-only results still use placeholders, but the placeholders are now type-aware:</p><ul><li>image-only results become <code>(see attached image)</code></li><li>audio-only results become <code>(see attached audio)</code></li><li>mixed image and audio results become <code>(see attached media)</code></li></ul><p>The patch also redacts or omits risky fields before replay. The PR explicitly calls out secret-like fields, inline data URIs, opaque encrypted fields, and binary <code>data</code> fields.</p><p>That is the right balance: preserve useful structured context, but do not turn provider replay into a raw data exfiltration path.</p><h2>Provider Coverage Is Broad</h2><p>This is not a one-provider patch. The implementation touches shared provider-side extraction and replay paths across OpenAI Responses, OpenAI Completions, Anthropic, Google shared provider handling, Mistral, OpenAI transport streams, and Anthropic transport streams.</p><p>The follow-up repair also closes a sibling gap in the bundled Google extension transport. The PR says <code>extensions/google/transport-stream.ts</code> still built <code>functionResponse.response.output</code> from explicit text or a media placeholder, so structured-only non-media results could still become empty output. The merged version gives Google transport the same structured replay behavior while keeping the helper boundary inside the private plugin SDK path.</p><p>That boundary detail matters for extension authors. The public Plugin SDK surface did not expand just to solve this internal replay issue.</p><h2>Validation</h2><p>The regression coverage is targeted and detailed. The PR reports tests for explicit-text precedence, structured JSON serialization, media-only omission from text extraction, image/audio/mixed placeholder selection, inline data URI and binary-field redaction, OpenAI replay behavior, Anthropic transport behavior, Google function response output, xAI audio fallback handling, and plugin SDK alias boundaries.</p><p>It also reports <code>plugin-sdk:surface:check</code>, extension package-boundary compilation across 116 bundled extension packages, focused Vitest shards, linting, and <code>git diff --check</code>.</p><h2>Bottom Line</h2><p>This is a reliability and safety fix for OpenClaw's tool transcript layer.</p><p>The important outcome is simple: if a tool returns structured, non-media information, OpenClaw should keep that information readable for the next model turn. If the tool returns media, OpenClaw should describe the media accurately. If the tool returns secrets or opaque binary fields, OpenClaw should not replay them raw.</p><p>PR #97742 moves provider replay closer to that standard across the main OpenClaw provider stack.</p><p><img src=\"https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-structured-tool-result-replay.png\" alt=\"OpenClaw Preserves Structured Tool Results\" /></p>",
      "date_published": "2026-07-01T08:10:00.000Z",
      "date_modified": "2026-07-09T08:12:14.646Z",
      "authors": [
        {
          "name": "Cody",
          "url": "https://openclawchronicles.com/about/",
          "avatar": "https://openclawchronicles.com/assets/images/authors/cody.jpg"
        }
      ],
      "tags": [
        "OpenClaw",
        "News",
        "Preserves",
        "Structured",
        "Tool",
        "Results"
      ],
      "image": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-structured-tool-result-replay.png",
      "attachments": [
        {
          "url": "https://openclawchronicles.com/assets/images/posts/openclaw-2026-7-1-structured-tool-result-replay.png",
          "mime_type": "image/png",
          "title": "OpenClaw Preserves Structured Tool Results cover image"
        }
      ]
    }
  ]
}
