Skip to content

feat(plugins): add session followup turn API and gateway-restart extension#63330

Closed
corbin-breton wants to merge 17 commits into
openclaw:mainfrom
corbin-breton:feat/followup-api-v2
Closed

feat(plugins): add session followup turn API and gateway-restart extension#63330
corbin-breton wants to merge 17 commits into
openclaw:mainfrom
corbin-breton:feat/followup-api-v2

Conversation

@corbin-breton

@corbin-breton corbin-breton commented Apr 8, 2026

Copy link
Copy Markdown

Summary

Add a new runtime.followup.enqueueFollowupTurn() method to the plugin runtime, enabling plugins to schedule proactive agent turns for any session — including cold sessions with no active user interaction.

Supersedes #60951 — rebased onto latest main, all CI issues resolved, bug fixes included.

Problem

Plugins have no way to inject a user-role message into an existing session and trigger an agent turn. The available primitives (enqueueSystemEvent, subagent.run) either don't initiate turns or create new sessions instead of continuing the original conversation. This blocks use cases like:

  • Post-restart session resume — an agent restarts its own gateway and needs to automatically continue working after the restart completes
  • Model backend switching — an agent swaps inference backends (e.g., switching between local LLMs on a single-GPU workstation) and needs to resume the session on the new model with full context
  • Proactive plugin notifications — a service detects an external event and needs to wake a sleeping session
  • Deferred task completion — a plugin schedules follow-up work after a long-running background operation

Solution

Core API: runtime.followup.enqueueFollowupTurn()

A new followup namespace on PluginRuntimeCore that:

  1. Reconstructs a full FollowupRun from the session store via buildFollowupRunForSession() — resolving agent identity, workspace, provider/model, session file, and delivery context from the persisted SessionEntry.

  2. Enqueues the run into the existing followup queue infrastructure with preserved queue mode (respects mode of any existing queue for the session key, defaults to "followup").

  3. Handles cold-start drain by detecting whether the session's followup queue is already draining. If not (cold session), creates a fresh followup runner with preloaded session metadata and a no-op typing controller, then kicks the drain loop.

// Plugin usage
const enqueued = await api.runtime.followup.enqueueFollowupTurn({
  sessionKey: "agent:my-agent:telegram:direct:12345",
  prompt: "Background task complete. Here are the results...",
  source: "my-plugin",
});

Bundled Extension: gateway-restart

A reference implementation that demonstrates the followup turn API:

  • Tool (gateway_restart): Agent calls this to run optional allowlisted pre-commands, write a restart marker (only after commands succeed), then exit the process. Systemd (or equivalent) auto-restarts the gateway.

  • Service (gateway-restart-watcher): On startup, checks for the restart marker. If found, calls enqueueFollowupTurn() to resume the original session with a completion message. Marker is deleted only after successful enqueue — preserved for retry on failure.

Disabled by default (enabledByDefault: false). Opt-in via plugins.entries.gateway-restart.enabled: true.

Files Changed

File Description
src/auto-reply/reply/queue/build-followup-run.ts New: cold-session FollowupRun builder with session store resolution
src/plugins/runtime/runtime-followup.ts New: plugin runtime followup namespace with hot/cold session detection
src/plugins/runtime/types-core.ts Add followup type to PluginRuntimeCore
src/plugins/runtime/index.ts Wire createRuntimeFollowup()
extensions/gateway-restart/index.ts New: gateway-restart plugin (tool + watcher service)
extensions/gateway-restart/openclaw.plugin.json New: plugin manifest
extensions/gateway-restart/package.json New: package metadata
test/helpers/plugins/plugin-runtime-mock.ts Add followup to mock
**/**.test.ts 24 unit tests across 3 test files

Bug Fixes (vs #60951)

  1. Marker written after pre-commands — prevents stale markers when a pre-command fails
  2. Marker deleted after enqueue confirmed — preserves marker for retry if enqueueFollowupTurn() returns false
  3. Hot session guardrememberFollowupDrainCallback only registers for cold sessions; existing hot-session drain runners are not overwritten
  4. Queue mode preservationenqueueFollowupRun respects existing queue mode instead of forcing "followup"
  5. Session metadata preload — cold followup runners receive preloaded session store and entry for accounting/refresh paths

Testing

  • 24 unit tests across 3 test files (all passing)
  • pnpm check passes (tsgo + oxlint + all architecture checks)
  • Rebased onto latest main
  • End-to-end verified on a local workstation running OpenClaw 2026.4.8 with Gemma 4 26B via llama.cpp

Use Cases This Enables

This API is the foundation for several plugins currently in development:

  • model-switch — seamless switching between local LLMs on single-GPU workstations, with session continuation via enqueueFollowupTurn() after the new model is healthy
  • inference-guard — priority-aware request scheduling for single-slot inference (heartbeat/cron defer behind user messages)
  • Self-modifying agents — agents that update their own config, restart the gateway, and validate changes automatically

Test plan

  • pnpm check passes
  • pnpm vitest run extensions/gateway-restart/index.test.ts — 6 tests pass
  • pnpm vitest run src/plugins/runtime/runtime-followup.test.ts — 9 tests pass
  • pnpm vitest run src/auto-reply/reply/queue/build-followup-run.test.ts — 9 tests pass
  • Gateway-restart tool writes marker only after pre-commands succeed
  • Watcher service enqueues followup turn and deletes marker on success
  • Watcher preserves marker on enqueue failure

AI Disclosure

This PR was developed with AI assistance (Claude Code). Testing level: fully tested — 24 unit tests, pnpm check green, end-to-end verified on local hardware. The author understands all code in this PR and can explain design decisions.

🤖 Generated with Claude Code

@greptile-apps

greptile-apps Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds runtime.followup.enqueueFollowupTurn() to the plugin runtime, enabling plugins to inject a user-role message into any session (hot or cold) and trigger an agent turn — plus a reference gateway-restart extension that writes a marker before exiting and resumes the original session on next startup.

  • P1 (extensions/gateway-restart/index.ts:139): execSync has no timeout option; a hung pre-command (e.g. slow openclaw gateway install --force) blocks the gateway process indefinitely, taking down all active sessions with no recovery path.
  • P2 (extensions/gateway-restart/index.ts:136): execSync failures propagate as unhandled exceptions out of execute() rather than returning a structured error result, inconsistent with the existing allowlist-rejection path.

Confidence Score: 4/5

Safe to merge after addressing the missing execSync timeout; the P1 is limited to the opt-in gateway-restart extension and does not affect the core followup API.

The core followup API (runtime-followup.ts, build-followup-run.ts, types-core.ts) is well-designed and has solid test coverage. The one P1 finding is in the bundled gateway-restart extension: execSync with no timeout can permanently stall the gateway process on a slow or hung pre-command. This is a real reliability defect on the changed path, warranting a 4 rather than 5.

extensions/gateway-restart/index.ts — the execSync timeout gap and error-propagation style.

Vulnerabilities

  • Command injection scope is correctly bounded — the allowlist is enforced via Set.has() before execution; agents cannot inject arbitrary commands.
  • Marker file contents are non-sensitive — only session key, timestamp, and optional message text are persisted; no credentials or API keys.
  • senderIsOwner: true on plugin-initiated turns — documented and consistent with the heartbeat/cron trust model; operators who enable this plugin should be aware that followup turns run with owner trust.
  • process.exit(0) scope — terminates the entire gateway (all sessions), as documented in the security comment block. Acceptable for an opt-in, operator-enabled plugin.
  • No other security concerns identified.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/gateway-restart/index.ts
Line: 139-144

Comment:
**No timeout on `execSync` can hang the gateway indefinitely**

`execSync` has no `timeout` option, so if a pre-command (e.g. `openclaw gateway install --force` during a slow network operation) stalls, the gateway process blocks forever — preventing both the restart and all active sessions from making progress. Since the gateway is single-process, one hung pre-command is a complete outage.

```suggestion
          const output = execSync(command, {
            encoding: "utf8",
            timeout: 5 * 60 * 1000, // 5-minute hard cap per command
            stdio: ["ignore", "pipe", "pipe"],
          });
```

Consider making the timeout configurable via `PluginConfig` if operators need longer windows for custom commands.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/gateway-restart/index.ts
Line: 136-145

Comment:
**`execSync` failure throws from `execute()` instead of returning an error result**

When a pre-command fails, `execSync` throws and the exception propagates out of `execute()` unhandled (confirmed by the test's `rejects.toThrow`). If the plugin runtime doesn't wrap tool callbacks in a try/catch, the agent receives an opaque framework error rather than a readable diagnostic. The existing allowlist-violation path already returns a structured error object — the command-failure path should match that pattern.

```suggestion
        let commandOutputs: string[] = [];
        try {
          for (const command of commands) {
            const output = execSync(command, {
              encoding: "utf8",
              stdio: ["ignore", "pipe", "pipe"],
            });
            commandOutputs.push(output);
          }
        } catch (err) {
          return {
            content: [
              {
                type: "text" as const,
                text: `ERROR: Pre-restart command failed: ${String(err instanceof Error ? err.message : err)}`,
              },
            ],
            details: null,
          };
        }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/runtime/runtime-followup.ts
Line: 24-37

Comment:
**Session store is loaded twice for every cold-session enqueue**

`buildFollowupRunForSession()` (called on line 19) already calls `loadSessionStore` internally to resolve the session entry. The try/catch block here reloads the same store a second time from the same path just to pass `sessionEntry` to the cold runner. This is two synchronous file-system reads for identical data. Consider returning the pre-loaded store/entry from `buildFollowupRunForSession` or accepting them as optional parameters so callers can pass through what they already have.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(plugins): preload session metadata f..." | Re-trigger Greptile

Comment thread extensions/gateway-restart/index.ts Outdated
Comment on lines +139 to +144
for (const command of commands) {
const output = execSync(command, {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
commandOutputs.push(output);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 No timeout on execSync can hang the gateway indefinitely

execSync has no timeout option, so if a pre-command (e.g. openclaw gateway install --force during a slow network operation) stalls, the gateway process blocks forever — preventing both the restart and all active sessions from making progress. Since the gateway is single-process, one hung pre-command is a complete outage.

Suggested change
for (const command of commands) {
const output = execSync(command, {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
commandOutputs.push(output);
const output = execSync(command, {
encoding: "utf8",
timeout: 5 * 60 * 1000, // 5-minute hard cap per command
stdio: ["ignore", "pipe", "pipe"],
});

Consider making the timeout configurable via PluginConfig if operators need longer windows for custom commands.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/gateway-restart/index.ts
Line: 139-144

Comment:
**No timeout on `execSync` can hang the gateway indefinitely**

`execSync` has no `timeout` option, so if a pre-command (e.g. `openclaw gateway install --force` during a slow network operation) stalls, the gateway process blocks forever — preventing both the restart and all active sessions from making progress. Since the gateway is single-process, one hung pre-command is a complete outage.

```suggestion
          const output = execSync(command, {
            encoding: "utf8",
            timeout: 5 * 60 * 1000, // 5-minute hard cap per command
            stdio: ["ignore", "pipe", "pipe"],
          });
```

Consider making the timeout configurable via `PluginConfig` if operators need longer windows for custom commands.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread extensions/gateway-restart/index.ts Outdated
Comment on lines +136 to +145
// Fix 1: Execute pre-commands BEFORE writing marker.
// If execSync throws, we never write the marker, preventing stale markers.
const commandOutputs: string[] = [];
for (const command of commands) {
const output = execSync(command, {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
commandOutputs.push(output);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 execSync failure throws from execute() instead of returning an error result

When a pre-command fails, execSync throws and the exception propagates out of execute() unhandled (confirmed by the test's rejects.toThrow). If the plugin runtime doesn't wrap tool callbacks in a try/catch, the agent receives an opaque framework error rather than a readable diagnostic. The existing allowlist-violation path already returns a structured error object — the command-failure path should match that pattern.

Suggested change
// Fix 1: Execute pre-commands BEFORE writing marker.
// If execSync throws, we never write the marker, preventing stale markers.
const commandOutputs: string[] = [];
for (const command of commands) {
const output = execSync(command, {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
commandOutputs.push(output);
}
let commandOutputs: string[] = [];
try {
for (const command of commands) {
const output = execSync(command, {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
commandOutputs.push(output);
}
} catch (err) {
return {
content: [
{
type: "text" as const,
text: `ERROR: Pre-restart command failed: ${String(err instanceof Error ? err.message : err)}`,
},
],
details: null,
};
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/gateway-restart/index.ts
Line: 136-145

Comment:
**`execSync` failure throws from `execute()` instead of returning an error result**

When a pre-command fails, `execSync` throws and the exception propagates out of `execute()` unhandled (confirmed by the test's `rejects.toThrow`). If the plugin runtime doesn't wrap tool callbacks in a try/catch, the agent receives an opaque framework error rather than a readable diagnostic. The existing allowlist-violation path already returns a structured error object — the command-failure path should match that pattern.

```suggestion
        let commandOutputs: string[] = [];
        try {
          for (const command of commands) {
            const output = execSync(command, {
              encoding: "utf8",
              stdio: ["ignore", "pipe", "pipe"],
            });
            commandOutputs.push(output);
          }
        } catch (err) {
          return {
            content: [
              {
                type: "text" as const,
                text: `ERROR: Pre-restart command failed: ${String(err instanceof Error ? err.message : err)}`,
              },
            ],
            details: null,
          };
        }
```

How can I resolve this? If you propose a fix, please make it concise.

Comment thread src/plugins/runtime/runtime-followup.ts Outdated
Comment on lines +24 to +37
let runnerStorePath: string | undefined;
let runnerSessionStore: ReturnType<typeof loadSessionStore> | undefined;
let runnerSessionEntry: ReturnType<typeof loadSessionStore>[string] | undefined;
try {
runnerStorePath = resolveStorePath(followupRun.run.config.session?.store, {
agentId: followupRun.run.agentId,
});
runnerSessionStore = loadSessionStore(runnerStorePath);
runnerSessionEntry = runnerSessionStore[params.sessionKey];
} catch (err) {
logVerbose(
`[runtime.followup] failed to preload session metadata for "${params.sessionKey}": ${String(err)}`,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Session store is loaded twice for every cold-session enqueue

buildFollowupRunForSession() (called on line 19) already calls loadSessionStore internally to resolve the session entry. The try/catch block here reloads the same store a second time from the same path just to pass sessionEntry to the cold runner. This is two synchronous file-system reads for identical data. Consider returning the pre-loaded store/entry from buildFollowupRunForSession or accepting them as optional parameters so callers can pass through what they already have.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugins/runtime/runtime-followup.ts
Line: 24-37

Comment:
**Session store is loaded twice for every cold-session enqueue**

`buildFollowupRunForSession()` (called on line 19) already calls `loadSessionStore` internally to resolve the session entry. The try/catch block here reloads the same store a second time from the same path just to pass `sessionEntry` to the cold runner. This is two synchronous file-system reads for identical data. Consider returning the pre-loaded store/entry from `buildFollowupRunForSession` or accepting them as optional parameters so callers can pass through what they already have.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e401fa1fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pnpm-lock.yaml Outdated
Comment on lines +39 to +41
'@aws-sdk/client-bedrock':
specifier: 3.1024.0
version: 3.1024.0
'@aws-sdk/client-bedrock-runtime':
specifier: 3.1024.0
version: 3.1024.0
'@aws-sdk/credential-provider-node':
specifier: 3.972.29
version: 3.972.29
'@aws/bedrock-token-generator':
specifier: ^1.1.0
version: 1.1.0
'@buape/carbon':
specifier: 0.14.0
version: 0.14.0(@discordjs/[email protected])([email protected])([email protected])
specifier: 3.1023.0
version: 3.1023.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Regenerate lockfile from current manifests

Update pnpm-lock.yaml so its root importer matches package.json again: this hunk downgrades locked specs (for example @aws-sdk/client-bedrock to 3.1023.0 while package.json still declares 3.1024.0), and the commit does not include corresponding manifest changes. That makes the lockfile stale relative to the manifests, which can fail pnpm install --frozen-lockfile in CI and/or install unintended downgraded runtime dependencies.

Useful? React with 👍 / 👎.

corbin-breton pushed a commit to corbin-breton/openclaw that referenced this pull request Apr 8, 2026
…errors, session store dedup

- Add 5-minute timeout to execSync in gateway-restart (prevents hung commands from blocking gateway)
- Wrap execSync failures in structured error result instead of throwing (matches allowlist-rejection pattern)
- Eliminate double session store load in runtime-followup by returning metadata from buildFollowupRunForSession via _sessionMeta
- Fix pnpm-lock.yaml to match current overrides config

Addresses Greptile review feedback on PR openclaw#63330.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65db810896

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +90 to +93
name: "gateway_restart",
label: "Gateway Restart",
description:
"Restart the current OpenClaw gateway process, optionally run allowlisted commands first, and deliver a completion callback to the provided session.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Mark gateway_restart as owner-only

This tool registration omits ownerOnly, so non-owner senders can still invoke it when the plugin is enabled and plugin tools are otherwise allowed. In src/agents/tool-policy.ts, owner gating only auto-applies to known core names (for example gateway) or tools explicitly marked ownerOnly: true; gateway_restart matches neither, so untrusted users can trigger gateway-wide restarts and run allowlisted pre-commands.

Useful? React with 👍 / 👎.

Comment on lines +95 to +99
async execute(_toolCallId, params) {
const parsed = params as GatewayRestartParams;
const commands = parsed.commands ?? [];
const allowedCommands = new Set(config.allowedCommands);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Enforce commands.restart policy in plugin restart path

The execution path performs a restart without checking commands.restart, which bypasses the global restart-disable policy once this plugin is enabled. The core gateway tool explicitly blocks restart when commands.restart=false (src/agents/tools/gateway-tool.ts), so this new tool introduces inconsistent behavior where operators who disabled restart actions can still be restarted through gateway_restart.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d038df492

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const agentId = params.agentId?.trim() || resolveAgentIdFromSessionKey(params.sessionKey);
const cfg = loadConfig();
const agentDir = resolveAgentDir(cfg, agentId);
const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Reuse session workspace for followup turns

buildFollowupRunForSession always derives workspaceDir from resolveAgentWorkspaceDir(cfg, agentId), but followup sessions can carry a persisted spawnedWorkspaceDir (for spawned/subagent sessions). That means a resumed followup can execute in the agent’s default workspace instead of the session’s actual workspace, so post-restart or deferred turns may run commands against the wrong files/repo and produce incorrect side effects. The run builder should prefer the session entry’s workspace when present before falling back to the agent default.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui app: macos App: macos labels Apr 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97bfb5549e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +29 to +32
const enqueued = enqueueFollowupRun(
params.sessionKey,
followupRun,
{ mode: existingMode ?? "followup" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Strip _sessionMeta before queueing followup runs

buildFollowupRunForSession attaches _sessionMeta.sessionStore (the full loaded session store), and this code enqueues that same object directly. As a result, each queued followup item keeps a full store snapshot alive until drain finishes; when plugins enqueue multiple followups for a large sessions file, memory usage scales with queue depth and can cause avoidable RSS spikes or OOM pressure. Keep _sessionMeta only for cold-runner setup, and enqueue a plain FollowupRun payload without the extra metadata.

Useful? React with 👍 / 👎.

Comment on lines +96 to +99
const parsed = params as GatewayRestartParams;
const commands = parsed.commands ?? [];
const allowedCommands = new Set(config.allowedCommands);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Validate sessionKey before executing gateway restart

The tool proceeds to pre-commands, marker write, and process.exit(0) without checking that sessionKey is non-empty. Since the schema accepts empty strings, a malformed tool call can restart the whole gateway with an unusable marker (sessionKey: ""), and the watcher later cannot enqueue the callback turn for the original conversation. Reject blank/whitespace session keys before running commands or scheduling restart.

Useful? React with 👍 / 👎.

@corbin-breton

Copy link
Copy Markdown
Author

CI on main is currently broken by two test regressions in checks-node-test (temp-path-guard weak randomness + delivery-context Telegram thread resolution). Fix PR: #63995. This PR needs a rebase onto main after that fix lands — the check-additional failures here are also from stale base code and will resolve with rebase.

@openclaw-barnacle openclaw-barnacle Bot removed app: macos App: macos app: web-ui App: web-ui labels Apr 10, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 27c9151196

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1 to +3
{
"name": "@openclaw/gateway-restart-plugin",
"version": "2026.4.4-beta.1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Regenerate lockfile for the new gateway-restart workspace

This commit introduces a new workspace package but does not update pnpm-lock.yaml with an importers.extensions/gateway-restart entry. With a shared workspace lockfile, adding a package without regenerating the lockfile leaves manifests and lock state out of sync, which can break pnpm install --frozen-lockfile in CI and deployment automation.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 314429da9e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1 to +5
{
"name": "@openclaw/gateway-restart-plugin",
"version": "2026.4.4-beta.1",
"private": true,
"description": "OpenClaw gateway restart plugin with session follow-up resume",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Declare @sinclair/typebox as a runtime dependency

Add a dependencies entry for @sinclair/typebox in this plugin manifest. The new plugin runtime imports TypeBox at extensions/gateway-restart/index.ts, but this package currently declares no runtime dependencies, so installs that run in the plugin directory (for example npm install --omit=dev outside the monorepo hoist) can load the plugin and fail with ERR_MODULE_NOT_FOUND before registration.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 586d3ec882

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +83 to +85
const sessionFile =
sessionEntry.sessionFile?.trim() ||
resolveSessionFilePath(sessionEntry.sessionId, sessionEntry, sessionFileOpts);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Normalize persisted sessionFile before followup execution

This builder trusts sessionEntry.sessionFile directly via sessionEntry.sessionFile?.trim(), which bypasses resolveSessionFilePath(...)'s path-containment and stale/corrupt fallback logic. If a stored session entry contains an outdated absolute path or malformed value, cold followup runs can read/write transcripts at unintended locations (or fail to deliver entirely) instead of safely normalizing/falling back to the canonical session transcript path.

Useful? React with 👍 / 👎.

Keats and others added 17 commits April 12, 2026 08:26
…nsion

Add a new `runtime.followup.enqueueFollowupTurn()` method to the plugin
runtime, enabling plugins to schedule proactive agent turns for any
session — including cold sessions with no active user interaction.

## Problem

Plugins have no way to inject a user-role message into an existing
session and trigger an agent turn. The available primitives
(`enqueueSystemEvent`, `subagent.run`) either don't initiate turns or
create new sessions instead of continuing the original conversation.

## Solution

### Core API: `runtime.followup.enqueueFollowupTurn()`

A new namespace on `PluginRuntimeCore` that:

1. Reconstructs a full `FollowupRun` from the session store via a new
   `buildFollowupRunForSession()` helper — resolving agent identity,
   workspace, provider/model, session file, and delivery context from
   the persisted `SessionEntry`.

2. Enqueues the run into the existing followup queue infrastructure.

3. Handles the cold-start drain problem by creating a fresh followup
   runner with a no-op typing controller and registering it as the
   drain callback, so the turn executes immediately even when no
   prior drain loop exists for that session.

### Bundled Extension: `gateway-restart`

A reference implementation and practical tool that demonstrates the
followup turn API:

- **Tool** (`gateway_restart`): Agent calls this to write a restart
  marker, run optional allowlisted pre-commands, then exit the process.
  Systemd (or equivalent) auto-restarts the gateway.

- **Service** (`gateway-restart-watcher`): On startup, checks for the
  restart marker. If found, calls `enqueueFollowupTurn()` to resume the
  original session with a completion message. The agent wakes up with
  full session context and continues working.

## Files

- `src/auto-reply/reply/queue/build-followup-run.ts` — Cold-session
  FollowupRun builder
- `src/plugins/runtime/runtime-followup.ts` — Plugin runtime namespace
- `src/plugins/runtime/types-core.ts` — Type surface addition
- `src/plugins/runtime/index.ts` — Wiring
- `extensions/gateway-restart/` — Bundled extension (tool + service)
- `test/helpers/plugins/plugin-runtime-mock.ts` — Test mock update

## Testing

End-to-end verified on an isolated sandbox gateway:

1. Agent reads config, makes a change, calls `gateway_restart`
2. Gateway exits, restarts, watcher consumes marker
3. `enqueueFollowupTurn()` fires, agent resumes with full context
4. Agent validates the config change persisted and reports success
…latest main

- Fix TS2339: use NonNullable<> wrapper for Partial<OpenClawPluginApi> parameter type
- Fix eslint(curly): add required braces after if conditions in test helpers

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…rve queue mode

buildFollowupRunForSession now passes the resolved storePath through
resolveSessionFilePathOptions so custom session.store locations produce
the correct transcript path on the fallback branch.

enqueueFollowupTurn reads the existing queue mode before enqueueing
instead of unconditionally forcing mode=followup, which could clobber
a hot session's collect/interrupt/steer mode mid-drain.

Targeted tests added for both fixes.
…errors, session store dedup

- Add 5-minute timeout to execSync in gateway-restart (prevents hung commands from blocking gateway)
- Wrap execSync failures in structured error result instead of throwing (matches allowlist-rejection pattern)
- Eliminate double session store load in runtime-followup by returning metadata from buildFollowupRunForSession via _sessionMeta
- Fix pnpm-lock.yaml to match current overrides config

Addresses Greptile review feedback on PR openclaw#63330.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Avoid serializing the full session store into every queued followup item.
Extract metadata for the cold runner, then pass only the clean FollowupRun
to enqueueFollowupRun.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The test harness mock for pi-embedded-helpers.js listed exports
explicitly but missed the recently added sanitizeUserFacingText.
Spread importActual so new exports are always included.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Two test failures have been breaking CI on main:

1. temp-path-guard: extensions/qa-lab/src/multipass.runtime.ts used
   Math.random() + Date.now() on the same line, triggering the weak
   randomness guardrail. Replace with crypto.randomBytes().

2. delivery-context: the Telegram test expected the generic "channel:"
   prefix for delivery targets, but the bundled Telegram plugin provides
   resolveDeliveryTarget which returns the raw chatId. Update the test
   expectation to match the actual bundled plugin behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Main updated the telegram parent-scoped thread delivery to use
'channel:' prefix. Align test expectation.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add the gateway-restart extension to the lockfile so CI's
frozen-lockfile install doesn't produce a dirty tree.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Main now explicitly mocks sanitizeUserFacingText. The
actualPiHelpers spread injects real implementations where
tests expect vi.fn() mocks, causing assertion failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 3, 2026, 7:06 PM ET / 23:06 UTC.

Summary
The PR adds a public runtime.followup.enqueueFollowupTurn() plugin runtime namespace, a bundled gateway-restart plugin/tool/service, tests, package metadata, lockfile changes, and an unrelated QA Multipass runtime change.

PR surface: Source +510, Tests +701, Config +15, Other +2. Total +1228 across 15 files.

Reproducibility: yes. for the patch risks by source inspection: the PR head shows model-supplied session targeting, a plugin-owned JSON restart marker, partial cold-run reconstruction, and removed QA concurrency forwarding. No live current-head restart proof was provided.

Review metrics: 5 noteworthy metrics.

  • Plugin/runtime surfaces: 1 runtime namespace added, 1 bundled plugin added, 1 tool/service pair added. These create new public SDK and privileged restart contracts that need maintainer ownership before merge.
  • Config/default surfaces: 2 added. allowedCommands and markerFileName are operator-facing defaults that affect setup and upgrade behavior.
  • Runtime state stores: 1 JSON marker sidecar added. The proposed marker competes with current SQLite-owned restart and delivery state.
  • QA runner option forwarding: 1 removed. The diff drops Multipass --concurrency forwarding while the CLI still accepts and passes that option.
  • Plugin runtime dependencies: 1 runtime import, 0 declared dependencies. The new plugin imports schema code but its package manifest does not own the runtime dependency.

Stored data model
Persistent data-model change detected: vector/embedding metadata: extensions/gateway-restart/index.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted current-head proof from a real gateway restart showing same-session continuation and no private data exposure.
  • Rework session targeting and restart continuation through trusted host-owned context and durable restart/session-delivery primitives.
  • [P1] Restore unrelated QA Multipass concurrency forwarding and fix the plugin dependency/import surface.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR claims local E2E testing, but no inspectable current-head terminal output, redacted logs, recording, screenshot with diagnostics, or linked artifact proves the real restart and continuation path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging as-is would add a second restart-continuation authority beside the current SQLite restart sentinel and durable session-delivery queue.
  • [P1] The proposed tool lets model-supplied sessionKey select the target for an owner-trusted follow-up turn, which can cross the current trusted session boundary.
  • [P1] Cold follow-up turns can resume with incomplete account, group, workspace, cwd, tool-policy, skills, elevation, or delivery context.
  • [P1] The branch adds a public plugin API plus operator config/defaults and state behavior without maintainer-confirmed SDK, upgrade, and security contract.
  • [P1] The PR still lacks inspectable real behavior proof for a current-head restart and same-session continuation path.
  • [P1] The branch carries unrelated QA Multipass changes that drop --concurrency forwarding.

Maintainer options:

  1. Rework Through Canonical Restart (recommended)
    Use the existing trusted gateway restart scheduler, SQLite restart sentinel, and durable session-delivery queue instead of a plugin-owned JSON marker and direct process exit.
  2. Pause For API Direction
    Hold the branch until maintainers confirm whether immediate cold-session follow-up should be a public plugin runtime API or a narrower host-owned workflow seam.
  3. Accept A Privileged Bundled Plugin
    Maintainers could intentionally accept the new privileged plugin contract, but should explicitly own the session-boundary, upgrade, and operator-policy risks before merge.

Next step before merge

  • [P1] Maintainers need to decide the public follow-up API and restart ownership model, and the contributor needs to provide real behavior proof before any merge path is safe.

Security
Needs attention: The diff introduces privileged restart and owner-trusted follow-up behavior with concrete session-boundary and operator-policy concerns.

Review findings

  • [P1] Derive the restart session from trusted context — extensions/gateway-restart/index.ts:36-39
  • [P1] Use the canonical gateway restart path — extensions/gateway-restart/index.ts:160-164
  • [P1] Preserve the full follow-up run context — src/auto-reply/reply/queue/build-followup-run.ts:107-119
Review details

Best possible solution:

Settle the public API and restart ownership boundary first, then rework the implementation through trusted session identity, current SQLite restart/session-delivery primitives, complete context reconstruction, SDK docs/contracts, focused tests, and redacted current-head real proof.

Do we have a high-confidence way to reproduce the issue?

Yes for the patch risks by source inspection: the PR head shows model-supplied session targeting, a plugin-owned JSON restart marker, partial cold-run reconstruction, and removed QA concurrency forwarding. No live current-head restart proof was provided.

Is this the best way to solve the issue?

No; this is a plausible prototype, but the maintainable merge shape should reuse current host-owned restart, sentinel, delivery, and trusted session boundaries rather than adding a parallel privileged plugin path.

Full review comments:

  • [P1] Derive the restart session from trusted context — extensions/gateway-restart/index.ts:36-39
    sessionKey is model-supplied tool input, but the marker later uses it to enqueue an owner-trusted follow-up turn. This needs to come from the trusted current session/tool context, not from arbitrary tool parameters, or one session can target another session's continuation.
    Confidence: 0.93
  • [P1] Use the canonical gateway restart path — extensions/gateway-restart/index.ts:160-164
    This writes a plugin-owned marker and exits the process directly, bypassing commands.restart, the SIGUSR1 restart scheduler, the SQLite restart sentinel, and durable session-delivery continuation. That creates a second restart contract that can ignore operator policy and lose the callback after a second crash.
    Confidence: 0.91
  • [P1] Preserve the full follow-up run context — src/auto-reply/reply/queue/build-followup-run.ts:107-119
    The cold-run builder only restores a subset of FollowupRun.run and hardcodes blockReplyBreak, while current runs carry account, group, cwd, skills, elevation, and delivery-policy fields. Cold plugin follow-ups can therefore run in the wrong workspace or with the wrong policy/session context.
    Confidence: 0.88
  • [P2] Import the declared TypeBox package — extensions/gateway-restart/index.ts:4-5
    The new plugin imports @sinclair/typebox, but this repo and existing plugin packages use typebox, and the new package manifest declares no runtime dependency. External or package-isolated plugin loading can fail before registration.
    Confidence: 0.9
  • [P2] Keep Multipass concurrency forwarding — extensions/qa-lab/src/multipass.runtime.ts:367-368
    The PR removes concurrency from the Multipass plan and no longer passes --concurrency to the guest QA command, while the CLI still parses and forwards that option. Users selecting a Multipass concurrency will silently get the default worker count instead.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.91

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 677c8ff8466d.

Label changes

Label justifications:

  • P2: This is a normal-priority feature/API PR with important but bounded plugin, restart, session-state, and proof blockers.
  • merge-risk: 🚨 compatibility: The PR adds public plugin API, plugin config defaults, a new package, and restart behavior that can affect existing operators and plugin authors.
  • merge-risk: 🚨 session-state: The new cold follow-up path reconstructs session runs from partial persisted data and can resume with missing or wrong session context.
  • merge-risk: 🚨 security-boundary: The gateway-restart tool trusts a model-supplied session key for owner-trusted continuation and bypasses current restart policy ownership.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR claims local E2E testing, but no inspectable current-head terminal output, redacted logs, recording, screenshot with diagnostics, or linked artifact proves the real restart and continuation path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +510, Tests +701, Config +15, Other +2. Total +1228 across 15 files.

View PR surface stats
Area Files Added Removed Net
Source 8 516 6 +510
Tests 5 702 1 +701
Docs 0 0 0 0
Config 1 15 0 +15
Generated 0 0 0 0
Other 1 2 0 +2
Total 15 1235 7 +1228

Security concerns:

  • [high] Model-supplied session target for owner-trusted turn — extensions/gateway-restart/index.ts:36
    The plugin accepts sessionKey from tool input and later enqueues a follow-up that the builder marks senderIsOwner: true, so a malformed or manipulated tool call can target a different session boundary.
    Confidence: 0.93
  • [high] Restart policy bypass through direct process exit — extensions/gateway-restart/index.ts:160
    The plugin writes its own marker and calls process.exit(0) instead of using the host restart scheduler that enforces commands.restart and owns durable sentinel cleanup.
    Confidence: 0.9

What I checked:

  • Root policy applied: Root review policy marks plugin APIs, auth/session state, config/defaults, startup/restart behavior, and fallback behavior as compatibility-sensitive and requires whole-surface review before PR verdicts. (AGENTS.md:27, 010b61746379)
  • Extension dependency boundary: The extension guide requires plugin runtime dependencies to belong to the owning plugin package, which matters because this PR imports a schema package from the new plugin without declaring dependencies. (extensions/AGENTS.md:23, 010b61746379)
  • Current canonical restart path: Current main's gateway tool checks commands.restart, builds the restart sentinel from a trusted session identity, and explicitly warns that model-supplied params must not queue work into another session. (src/agents/tools/gateway-tool.ts:461, 010b61746379)
  • Current durable restart continuation: Current main's restart sentinel startup path resolves session delivery context and enqueues an agent-turn continuation through durable session delivery rather than a plugin-owned sidecar file. (src/gateway/server-restart-sentinel.ts:569, 010b61746379)
  • Current durable delivery queue: Current main persists session delivery entries in the shared SQLite-backed delivery queue with idempotency, retry, and acknowledgement semantics. (src/infra/session-delivery-queue-storage.ts:85, 010b61746379)
  • Current follow-up run contract: FollowupRun carries account, group, sender, policy, cwd, skills, execution, reply, and delivery fields that the PR's cold-run builder only partially reconstructs. (src/auto-reply/reply/queue/types.ts:96, 010b61746379)

Likely related people:

  • steipete: Peter Steinberger appears repeatedly in recent restart, follow-up, and plugin SDK history, including follow-up delivery extraction and restart scheduling/test hardening. (role: recent area contributor; confidence: high; commits: 43e6c923ded1, 2721245848cc, b31836317a47; files: src/gateway/server-restart-sentinel.ts, src/infra/restart-sentinel.ts, src/auto-reply/reply/followup-runner.ts)
  • vincentkoc: Vincent Koc has recent work on follow-up drain callbacks, prompt-cache follow-ups, session delivery, and plugin SDK surfaces touched by this PR's proposed API. (role: recent area contributor; confidence: high; commits: a35dcf608e8e, 02e07a157d22, 577983172307; files: src/auto-reply/reply/queue/types.ts, src/auto-reply/reply/queue/enqueue.ts, src/plugins/types.ts)
  • gumadeiras: Gustavo Madeira Santana has recent restart-sentinel routing and plugin SDK checkout/import work that overlaps the PR's restart-continuation and plugin dependency surfaces. (role: adjacent owner; confidence: medium; commits: 9c44f100266e, 9b44929f285b, 110f8bd2e1e2; files: src/gateway/server-restart-sentinel.ts, src/infra/restart-sentinel.ts, src/plugins/types.ts)
  • jalehman: Josh Lehman is connected to recent session transcript and plugin runtime ownership work that may affect the SDK boundary for a new follow-up API. (role: adjacent owner; confidence: medium; commits: 77a0ee7f9de7, 799c6f40aa69; files: src/config/sessions, src/plugins, src/plugin-sdk)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@corbin-breton

Copy link
Copy Markdown
Author

Wow, I haven't touched this in a minute, just got married and life has been busy. Glad to see that people are still working out the kinks and adapting it for the evolving OpenClaw development ecosystem.

My goal of this PR was to shed some light on how we can make OpenClaw continuously work even if the running agent has to make a configuration change to itself and restart. This is important because it allows for rapid, agent driven setup, adding in a sort of "hot-reload" type feature that let the agent continue after changes.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks @corbin-breton. Closing this stale feature branch, not treating the follow-up/restart extension design as settled. It still has unresolved security, session-ownership, and restart-lifecycle blockers, and the author noted the branch was no longer active. Any revival should start from current main, define the public plugin/session ownership contract first, and prove behavior across a real gateway restart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: qa-lab merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants