openclaw/docs/plugins
PollyBot13 dba4da1f8b
fix(channels): keep deeper queued messages alive through long turns (#133248)
## Contributor description — original implementation

The contributor’s original description follows. Historical heads, scope and open decisions in this section refer to that implementation; the reviewed current implementation, compatibility decision and proof are recorded in the maintainer update below.

Closes #133245.

Related: #127950. This supersedes the current-main-incompatible queue-owned approach in #125385 while preserving today's canonical timeout retry disposition.

## What Problem This Solves

A durably claimed channel message can wait behind another follow-up turn for longer than the five-minute claim-to-adoption watchdog. Existing liveness renewal covers queue-head active-run admission checks, but not an ingress-backed lifecycle waiting deeper in the follow-up queue. The claim can therefore be retired before the message reaches the model.

## Why This Change Was Made

The follow-up queue now owns periodic deferred heartbeats for the exact ingress lifecycle while it remains in pending items, in-flight delivery, summary sources, or compacted summary elisions.

Ingress supplies a cadence derived from one third of its adoption-stall timeout. Debounce, Plugin SDK fan-in, and channel lifecycle wrappers preserve the shortest applicable cadence. Queue ownership triggers an immediate renewal, then periodic renewal; it stops after successful adoption, completion, ownership loss, or callback failure. A rejected adoption callback keeps renewal alive for the supported retry path.

The existing watchdog and canonical timeout retry policy remain unchanged, so silent handlers and orphaned claims still recover normally.

## User Impact

Messages accepted by durable channel ingress remain adoptable while they wait behind long-running work instead of silently disappearing before model execution. No setting or migration is required.

## Evidence

SDK documentation polish (2026-09-10, head `76097fef9397a04c10637e06dfaf64ebb6ca104a`): the public channel SDK guide now documents forwarding both heartbeat fields, the shortest-positive-finite fan-in cadence, renewal termination, and compatibility when older wrappers omit the optional cadence. The documentation-only addition passed changed-page formatting, MDX sanity, and `git diff --check`; production code and the previously tested runtime head below are unchanged. Current-head hosted CI has completed successfully; the final exact-head ClawSweeper review accepts the implementation and proof, leaving only SDK-owner acceptance of the documented contract.

Refreshed on 2026-09-08 for exact head `57c4faff0ed7bb2d9b4fd308aa46b19ae4095e61`, rebased onto `1ff45cad5a`.

- Preserved upstream's ingress-monitor type extraction and gateway-suspension repair; the optional cadence field follows its new type owner.
- Repaired the retry integration fixture: after real enqueue and initial renewal, only the abandoned message's heartbeat callback fails. The real watchdog then recovers it. Retry delivery, healthy sibling cleanup, and true duplicate assertions remain intact; no production behavior or timeout changed for this repair.
- 102 focused tests pass: dispatch ingress retry, queue in-flight/dedupe, ingress lifecycle/watchdog, Plugin SDK fan-in, Discord queue handling, and Slack handler.
- Changed-file gates pass: core/core-test/extension typechecks, formatting, changed core/extension lint, SDK boundaries/exports, dead-export scans, and repository guards.
- Fresh independent source review found no actionable P0–P2 defects. The standalone autoreview CLI failed at startup without a verdict and is not counted as review coverage.
- Current-head CI run [34520397963](https://github.com/openclaw/openclaw/actions/runs/34520397963) completed successfully. The earlier startup subprocess timeout is historical, not a current failing gate. Exact-head ClawSweeper review (September 10, 20:00 UTC) reports no actionable correctness or proof findings; explicit SDK-owner acceptance remains required before merge.
- Existing regressions cover immediate renewal after late handoff, periodic deeper-queue renewal, stopping after owner loss, and continuing across a rejected adoption callback.

Exact-head durable-ingress boundary proof used isolated SQLite with the production ingress drain/lifecycle binder, follow-up queue, and canonical adoption helper. The model callback was synthetic; this is not live Telegram or Discord transport proof. No production Gateway, channel state, or configuration was touched. Temporary state and queue ownership were cleaned up.

```json
{
  "schema": "openclaw.pr133248.durable-ingress-proof.v1",
  "exactHead": "57c4faff0ed7bb2d9b4fd308aa46b19ae4095e61",
  "setup": {
    "durableStore": "isolated OpenClaw SQLite state",
    "executor": "production follow-up queue with synthetic model callback",
    "transportLifecycle": "production ingress drain lifecycle",
    "adoptionStallTimeoutMs": 180
  },
  "queuedBehindLongTurn": {
    "heldMs": 620,
    "formerDeadlineCrossed": true,
    "heartbeatCount": 11,
    "claimStillOwnedAtCheckpoint": [
      "queued-event"
    ],
    "retryRowsAtCheckpoint": 0,
    "failedRowsAtCheckpoint": 0,
    "executionCount": 1,
    "duplicateAfterAdoption": "completed"
  },
  "orphanRecovery": {
    "status": "released-for-retry",
    "attempts": 1,
    "lastErrorContainsHandlerTimeout": true
  },
  "productionTouched": false
}
```

Owner acceptance:
- Intended behavior: accepted messages remain adoptable while their exact lifecycle is owned by the queue; ownerless claims retain canonical timeout recovery.
- Boundary: one optional cadence field propagated through existing shared lifecycle and channel wrappers; no configuration, schema, or migration change.
- Maintainer decision remains open: accept the additive public Plugin SDK lifecycle field and its queue-owned cadence semantics. Bot review is not that acceptance.
- Rollback: revert the renewal fix and its companion retry-fixture adjustment.
- Scope: 23 files, +273/-2. The width is required lifecycle forwarding; renewal policy stays in the queue and ingress drain.

AI-assisted.

---

## Maintainer update — reviewed head `9325ad501aa4`

## What Problem This Solves

Messages accepted while a long reply is running can expire in the follow-up queue and consume a retry. The reproduction confirmed expiry and retry; all three messages eventually arrived. It did not reproduce the older permanent-loss report in #133245.

## Fix and impact

The queue starts one heartbeat when it accepts a lifecycle and stops it on adoption, completion, cancellation, or callback failure. Heartbeats no longer scan queue collections or copy the in-flight set. Ingress remains responsible for the watchdog and retry settlement, and a heartbeat cannot undo the watchdog pause during adoption finalization.

Ingress derives the cadence from its adoption timeout. The optional lifecycle metadata remains necessary because wrappers rebuild callbacks and combine abort signals, losing the original timeout. No channel setting, schema, migration, dependency, or protocol change is added.

The simplification removes 110 lines net from the initial implementation plus main merge. Total production growth is 40 lines. Existing lifecycle types are reused, and the queue cases share the existing lifecycle test fixtures.

## Evidence

- Real Gateway and Discord: three marked messages on one route, with a queued reply held for 330 seconds. Main expired the third claim after 300.004 seconds. This head retained the same claim at 322.257 seconds with zero attempts; replies arrived once, in order, at 17.804, 349.201, and 350.223 seconds.
- Real SQLite/drain/binder/queue controls: explicit abandonment releases the claim; callback failure stops renewal and lets the watchdog retry without model execution.
- 191 core owner/sibling tests and 190 channel tests passed. All five new regression cases failed on plain main for the intended reasons.
- The local preflight passed core/extension type-aware lint, production and test types, script types, and protocol checks in an isolated checkout of this head.
- External consumers compiled and ran against published 2026.9.4 and this head, including omitted metadata, forwarding, optional return fields, and asynchronous abandonment.

## Consumers

Shared ingress binding, batching, reply dispatch, and the Feishu, Slack, Telegram, and Twitch wrappers preserve the source cadence. The fan-in uses the shortest valid cadence. Legacy wrappers that omit the optional field retain their existing head-only heartbeat behavior. Adoption, queue clearing, overflow, cancellation, summaries, and drain replacement retain or finish the same lifecycle owner.

Closes #133245.

Original implementation and report by @PollyBot13 (#133245). The contributor's commits and authorship are retained.

AI-assisted.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-14 10:52:52 +05:30
..
architecture-internals fix(plugins): reuse registrations with prepared metadata (#146703) 2026-09-12 21:42:32 -07:00
codex-harness fix: skip official setup approvals and default to Astra (#145646) 2026-09-12 00:34:25 -07:00
codex-harness-reference fix(codex): isolate hook imports and cancel disconnected waits (#147444) 2026-09-14 07:14:04 +08:00
codex-harness-runtime refactor(hooks): await stored MCP policy within relay lifetime (#145164) 2026-09-11 14:06:38 -07:00
google-meet fix(google-meet): honor summary output paths (#147078) 2026-09-13 07:55:10 -07:00
hooks docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
manifest feat: give every plugin a compact chat activity icon (#147333) 2026-09-13 13:49:51 -07:00
reference feat: share selected sessions read-only with a paired team Gateway (#136253) 2026-09-12 13:35:17 -07:00
sdk-agent-harness fix(agents): use exact model rows for harness support (#147849) 2026-09-13 21:59:55 -07:00
sdk-channel-plugins fix(channels): keep replies working after hot config reloads (#147001) 2026-09-13 06:31:50 -07:00
sdk-entrypoints feat(code-mode): infer results from the requested action (#147291) 2026-09-13 13:33:49 -07:00
sdk-migration refactor(plugins): deprecate synchronous keyed storage (#145158) 2026-09-11 12:45:23 -07:00
sdk-overview fix(models): reclaim plugin captures after catalog workers stop (#146513) 2026-09-12 17:31:32 -07:00
sdk-provider-plugins fix: avoid repeated catalog refreshes after slow discovery (#146665) 2026-09-12 20:02:37 -07:00
sdk-runtime fix(tasks): record execution ownership and settle orphaned records at restore (#147585) 2026-09-13 19:08:26 -07:00
voice-call feat(voice): share GPT Live across meetings and calls (#146546) 2026-09-12 17:06:51 -07:00
adding-capabilities.md docs(plugins,providers): close open link-audit findings for plugins and providers (#143021) 2026-09-09 19:49:52 +09:00
admin-http-rpc.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
architecture-internals.md docs(plugins): split the plugin architecture internals by reader job (#142730) 2026-09-09 08:58:45 +08:00
architecture.md fix(models): reclaim plugin captures after catalog workers stop (#146513) 2026-09-12 17:31:32 -07:00
beam.md fix(ui): hide deleted Beams immediately in the sidebar (#147460) 2026-09-13 15:12:48 -07:00
building-plugins.md feat: give every plugin a compact chat activity icon (#147333) 2026-09-13 13:49:51 -07:00
bundles.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
cli-backend-plugins.md fix: skip official setup approvals and default to Astra (#145646) 2026-09-12 00:34:25 -07:00
codex-computer-use.md fix(codex): isolate hook imports and cancel disconnected waits (#147444) 2026-09-14 07:14:04 +08:00
codex-harness-reference.md docs: fix information-architecture findings in plugins and channels docs (#143926) 2026-09-10 18:22:51 +08:00
codex-harness-runtime.md docs(plugins): split the Codex harness runtime page by reader job (#143458) 2026-09-10 08:21:48 +09:00
codex-harness.md fix(codex): isolate hook imports and cancel disconnected waits (#147444) 2026-09-14 07:14:04 +08:00
codex-native-plugins.md fix(codex): isolate hook imports and cancel disconnected waits (#147444) 2026-09-14 07:14:04 +08:00
codex-supervision.md fix(ui): make coding session discovery settings easy to find (#146502) 2026-09-12 17:03:20 -07:00
community.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
compatibility.md refactor(plugins): deprecate synchronous keyed storage (#145158) 2026-09-11 12:45:23 -07:00
copilot.md chore(deps): advance cooled TypeBox, AWS and Copilot SDKs (#145381) 2026-09-11 20:15:55 -07:00
dependency-resolution.md build(plugins): emit declared private worker entries (#144821) 2026-09-11 03:02:51 -07:00
feature-plugins.md refactor(ui): share Workboard selection and appearance controls (#144748) 2026-09-13 17:11:33 -03:00
geolocation.md feat(geolocation): resolve client addresses to a coarse city via a bundled plugin (#128546) 2026-08-24 04:56:03 -07:00
google-meet.md feat(voice): share GPT Live across meetings and calls (#146546) 2026-09-12 17:06:51 -07:00
hooks.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
install-overrides.md
llama-cpp.md docs: close remaining one-way link findings in cli, plugins, tools, providers (#143855) 2026-09-10 16:15:08 +08:00
logbook.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
manage-plugins.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
manifest.md fix(signal): start accounts with spaced keys without Doctor (#145750) 2026-09-12 16:35:19 +05:30
meeting-plugins.md feat(voice): share GPT Live across meetings and calls (#146546) 2026-09-12 17:06:51 -07:00
memory-lancedb.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
memory-wiki.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
message-presentation.md feat(line): let a LINE tap answer the question an agent asked (#133421) 2026-09-10 20:31:40 -07:00
oc-path.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
onepassword.md docs: close remaining one-way link findings in cli, plugins, tools, providers (#143855) 2026-09-10 16:15:08 +08:00
plugin-inventory.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
plugin-permission-requests.md docs: STE pass on terminology consistency and run-on sentences (#143770) 2026-09-10 15:51:49 +09:00
reference.md feat: share selected sessions read-only with a paired team Gateway (#136253) 2026-09-12 13:35:17 -07:00
sdk-agent-harness.md docs(plugins,providers): close open link-audit findings for plugins and providers (#143021) 2026-09-09 19:49:52 +09:00
sdk-channel-inbound.md feat(auto-reply): bounded multi-agent group threads on every channel (#141411) 2026-09-11 23:27:09 -07:00
sdk-channel-ingress.md docs: fix 20 link defects confirmed live in the verified backlog (#144133) 2026-09-11 03:48:10 +08:00
sdk-channel-outbound.md fix(channels): keep deeper queued messages alive through long turns (#133248) 2026-09-14 10:52:52 +05:30
sdk-channel-plugins.md fix: Nostr profile actions fail for paired dashboard operators (#145932) 2026-09-12 19:06:42 +05:30
sdk-entrypoints.md docs: Simplified Technical English pass over tools, plugins, and channels (#143979) 2026-09-10 19:21:31 +08:00
sdk-migration.md docs: Simplified Technical English pass over tools, plugins, and channels (#143979) 2026-09-10 19:21:31 +08:00
sdk-overview.md feat(plugins): expose the selected runtime entry (#144818) 2026-09-11 02:58:13 -07:00
sdk-provider-plugins.md fix(auth): make chat login and model-access recovery actionable (#145051) 2026-09-12 09:55:23 +05:30
sdk-runtime.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
sdk-setup.md chore(deps): advance cooled dependencies and major upgrades (#146258) 2026-09-12 13:28:12 -07:00
sdk-subpaths.md fix: restore plugin networking under Bun (#147421) 2026-09-13 19:25:19 -07:00
sdk-testing.md refactor(plugins): remove unused provider wizard option projection (#146695) 2026-09-13 15:31:05 -07:00
session-share.md fix(session-share): hide subagents and tool activity (#146598) 2026-09-12 18:19:41 -07:00
team-reports.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
teams-meetings.md feat(voice): share GPT Live across meetings and calls (#146546) 2026-09-12 17:06:51 -07:00
tool-plugins.md fix(memory): explain partial search timeouts and allow 30 seconds (#147702) 2026-09-13 19:34:11 -07:00
vault.md docs(start): correct headless credential handoff to the SQLite auth store (#131024) 2026-08-27 09:40:27 -07:00
voice-call.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
webhooks.md refactor(tasks): move managed child linkage to shared worker (#146678) 2026-09-12 22:49:31 -07:00
workboard.md feat(workboard): add selection and bulk card actions (#144756) 2026-09-13 17:11:35 -03:00
zalouser.md docs(plugins): remove obsolete Gateway restart guidance (#146516) 2026-09-12 16:48:13 -07:00
zoom-meetings.md feat(voice): share GPT Live across meetings and calls (#146546) 2026-09-12 17:06:51 -07:00