Skip to content

fix(channels): stop unavailable targets repeating plugin scans#100377

Merged
steipete merged 2 commits into
openclaw:mainfrom
xialonglee:fix/heartbeat-delivery-bootstrap-latency
Jul 11, 2026
Merged

fix(channels): stop unavailable targets repeating plugin scans#100377
steipete merged 2 commits into
openclaw:mainfrom
xialonglee:fix/heartbeat-delivery-bootstrap-latency

Conversation

@xialonglee

@xialonglee xialonglee commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where heartbeat and other outbound delivery routes could repeat a full runtime-plugin scan whenever an explicit or session-derived external channel target remained unavailable. A failed activation removed its retry guard, so recurring target resolution could pay the same expensive bootstrap cost on every attempt.

Why This Change Was Made

The retry invariant now lives in the shared outbound channel bootstrap owner. Failed attempts are remembered per channel, canonical runtime-config key, and combined pinned/active plugin-registry generation; a real config or registry reload allows one new attempt. A bounded 64-generation LRU preserves interleaved agent configs without unbounded process state.

This keeps activation available to every existing caller. It does not add heartbeat-specific preactivation, disable plugin bootstrap, or change unavailable-channel reporting.

User Impact

An unavailable or misconfigured external channel target now follows the normal no-target path without repeatedly rescanning every installed plugin. Fixing configuration or reloading the plugin registry still permits recovery immediately, with no new configuration required.

Evidence

  • Final pushed head: 1cb78cba2434eca714d42e0d7774494eee424ae2; the rebase preserves the reviewed code patch and adds maintainer-owned changelog credits.
  • Blacksmith Testbox focused proof: corepack pnpm test src/infra/outbound/channel-bootstrap.runtime.test.ts src/infra/outbound/channel-resolution.test.ts — 2 files, 34/34 tests passed.
  • Blacksmith Testbox changed gate: core and coreTests lanes passed with 0 warnings/errors.
  • Disposable real Gateway with a minimal external channel fixture lacking a send surface: the first explicit target caused one activation and repeats caused none; canonical config reload allowed one new activation; canonical registry reload allowed one new target:last activation; every unavailable route remained no-target. Success marker: OPENCLAW_PR100377_LIVE_CLEAN_OK.
  • Fresh branch-scoped Codex autoreview: no findings; patch correct; confidence 0.84.
  • Hosted exact-head validation: run 29145988256.

Co-authored-by: Peter Lee [email protected]

@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 11, 2026, 4:28 AM ET / 08:28 UTC.

Summary
The PR adds a bounded per-config and per-registry-generation guard for failed outbound channel plugin bootstraps, updates focused tests, and adds release changelog credits.

PR surface: Source +38, Tests +57, Docs +3. Total +98 across 4 files.

Reproducibility: yes. source inspection gives a high-confidence path: failed bootstrap attempts previously removed their marker, so the next bootstrap-enabled outbound resolution repeated the registry loader. The current replacement’s non-canonical full-config hashing is also directly source-reproducible, though no live benchmark was run in this read-only review.

Review metrics: 1 noteworthy metric.

  • Retry cache bound: 64 config generations. The LRU bounds process-local state for interleaved agent-scoped configs, but its key must remain cheap on the shared delivery hot path.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
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:

  • Replace full-config hashing with a prepared lifecycle config identity.
  • Post redacted current-head gateway logs showing one failed bootstrap per generation and retry after config or registry reload.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The posted gateway logs demonstrate the superseded heartbeat-preactivation implementation, not the current config/registry generation guard; add redacted exact-head logs, update the PR body, and request @clawsweeper re-review if automatic review does not run.

Risk before merge

  • [P1] Suppressing retries changes recovery behavior for all bootstrap-enabled outbound callers, so a stale key could leave an external channel unavailable until a recognized config or registry lifecycle change.
  • [P2] The non-canonical config fallback serializes and hashes the full config on repeated unresolved deliveries, preserving avoidable request-time work on the hot path the PR is intended to protect.
  • [P1] The branch lacks real current-head evidence that one failed activation is suppressed and a legitimate config or registry reload re-enables activation.

Maintainer options:

  1. Fix the key and prove recovery (recommended)
    Replace non-canonical full-config hashing with a prepared lifecycle identity, preserve registry/config re-arming, and add redacted exact-head gateway proof before merge.
  2. Pause the retry-semantics change
    Keep the PR open but do not merge until maintainers can verify that every supported plugin availability change re-arms the suppression guard.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
replace the non-canonical full-config hash in outbound bootstrap retry suppression with a cheap lifecycle-owned config generation identity; preserve the 64-entry bound, per-channel suppression, and registry-generation re-arming; update focused tests without editing CHANGELOG.md

Next step before merge

  • [P1] The branch has one narrow mechanical hot-path repair suitable for automation; contributor-specific exact-head real behavior proof must still be supplied separately before merge.

Security
Cleared: The diff adds in-process retry bookkeeping and tests without changing dependencies, permissions, secrets, workflow execution, package resolution, or downloaded code.

Review findings

  • [P2] Avoid hashing the full config on every bootstrap miss — src/infra/outbound/channel-bootstrap.runtime.ts:31
Review details

Best possible solution:

Use a cheap lifecycle-owned config generation identity prepared before outbound resolution, retain the bounded per-channel and registry-generation guard, and prove suppression plus recovery on the exact head in a real gateway.

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

Yes, source inspection gives a high-confidence path: failed bootstrap attempts previously removed their marker, so the next bootstrap-enabled outbound resolution repeated the registry loader. The current replacement’s non-canonical full-config hashing is also directly source-reproducible, though no live benchmark was run in this read-only review.

Is this the best way to solve the issue?

No, not yet. The shared bootstrap seam is a better owner than heartbeat-specific preactivation, but request-time stable serialization and hashing of agent-scoped configs conflicts with the hot-path goal; a prepared lifecycle identity is safer and narrower.

Full review comments:

  • [P2] Avoid hashing the full config on every bootstrap miss — src/infra/outbound/channel-bootstrap.runtime.ts:31
    Use a cheap lifecycle-owned config generation key here. resolveRuntimeConfigCacheKey only reuses metadata for the exact canonical runtime snapshot; agent-scoped or cloned configs fall back to stable serialization plus SHA-256, so every repeated unresolved delivery still walks and hashes the full config before this guard returns. This prior finding remains unchanged on the current head and replaces the eliminated registry scan with avoidable request-time work on the shared outbound hot path.
    Confidence: 0.93

Overall correctness: patch is incorrect
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp. Replaced prior rating: 🦐 gold shrimp.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P1: The reported repeated plugin scan can block a live heartbeat delivery workflow for roughly a minute on each tick.
  • merge-risk: 🚨 compatibility: The patch intentionally stops activation retries that external-plugin flows currently perform within the same process lifecycle.
  • merge-risk: 🚨 message-delivery: An incorrectly keyed or re-armed guard could leave a newly available channel unresolved and prevent heartbeat delivery.
  • merge-risk: 🚨 availability: The changed shared path controls both repeated long registry scans and replacement request-time work during outbound delivery.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp. Replaced prior rating: 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The posted gateway logs demonstrate the superseded heartbeat-preactivation implementation, not the current config/registry generation guard; add redacted exact-head logs, update the PR body, and request @clawsweeper re-review if automatic review does not run.
Evidence reviewed

PR surface:

Source +38, Tests +57, Docs +3. Total +98 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 1 50 12 +38
Tests 2 80 23 +57
Docs 1 3 0 +3
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 133 35 +98

Acceptance criteria:

  • [P1] pnpm test src/infra/outbound/channel-bootstrap.runtime.test.ts src/infra/outbound/channel-resolution.test.ts.
  • [P1] git diff --check.

What I checked:

  • Blocking hot-path cost: The new guard calls resolveRuntimeConfigCacheKey before returning from every repeated miss; that helper performs stable serialization and SHA-256 for any config object other than the exact canonical runtime snapshot. (src/infra/outbound/channel-bootstrap.runtime.ts:31, 1cb78cba2434)
  • Re-review continuity: The runtime file is unchanged from the previously reviewed ff36e26 head, where this same P2 was raised, so the finding remains unresolved rather than newly discovered. (src/infra/outbound/channel-bootstrap.runtime.ts:31, 1cb78cba2434)
  • Lifecycle design: The patch clears suppression when either the pinned channel registry or active plugin registry version changes, and bounds interleaved config entries to a 64-entry LRU. (src/infra/outbound/channel-bootstrap.runtime.ts:17, 1cb78cba2434)
  • Registry contract: setActivePluginRegistry increments the active version and refreshes tracked surfaces, supporting re-arming after explicit registry replacement. (src/plugins/runtime.ts:198, f71255e47566)
  • Proof mismatch: The PR body’s real gateway timeline reports heartbeat pre-activation and no-bootstrap resolution, but the current head instead changes the shared failed-bootstrap generation guard; no current-head live output demonstrates suppression or recovery. (1cb78cba2434)
  • Validation state: Current-head GitHub checks are green, including channel/plugin contract and security lanes, but CI does not replace the required real behavior proof. (1cb78cba2434)

Likely related people:

  • steipete: Authored the current rewritten implementation and tests, force-pushed the reviewed head, and is assigned to the PR. (role: recent area contributor; confidence: high; commits: be86e97e582f, 1cb78cba2434; files: src/infra/outbound/channel-bootstrap.runtime.ts, src/infra/outbound/channel-bootstrap.runtime.test.ts, src/infra/outbound/channel-resolution.test.ts)
  • AmirF194: Previously traced the shared doctor and runtime caller behavior and reviewed the bootstrap ownership boundary in this PR discussion. (role: reviewer and adjacent owner; confidence: medium; files: src/infra/outbound/channel-bootstrap.runtime.ts, src/infra/outbound/channel-resolution.ts, src/infra/outbound/targets.ts)
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.
Review history (27 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-07T17:49:17.074Z sha b63f951 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-07T17:58:21.060Z sha b63f951 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-08T01:16:07.799Z sha 9a37f34 :: needs real behavior proof before merge. :: [P1] Classify external targets before registration
  • reviewed 2026-07-08T01:23:56.865Z sha 9a37f34 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T02:41:54.543Z sha 9a37f34 :: needs changes before merge. :: [P1] Normalize targets before external preactivation checks
  • reviewed 2026-07-08T02:52:14.171Z sha 9a37f34 :: needs changes before merge. :: [P1] Normalize targets before external preactivation checks
  • reviewed 2026-07-08T05:01:57.622Z sha d5b03d3 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T07:40:27.575Z sha ff36e26 :: needs real behavior proof before merge. :: [P2] Avoid hashing the full config on every bootstrap miss

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels Jul 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: M and removed size: S labels Jul 5, 2026
@xialonglee

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 6, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 6, 2026
@AmirF194

AmirF194 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Reviewed at 5373b541bd4da227466d5510d0c5a2547a0be003. The direction is right — pulling the resolveRuntimePluginRegistry scan off the wake path and doing it once at startup matches the hot-path guidance, and the root cause (the bootstrapAttempts guard in src/infra/outbound/channel-bootstrap.runtime.ts:63-88 clearing on failed loads so every tick re-scans) is accurately diagnosed. Two things before this lands, plus one question:

  1. Cross-caller regression via the shared function. resolveHeartbeatDeliveryTarget isn't only the wake path — src/commands/doctor-heartbeat-session-target.ts:95 (describeHeartbeatSessionTargetIssues, run from src/commands/doctor-state-integrity.ts:1379) calls it too, and previously relied on allowBootstrap: true to resolve an external-plugin target standalone. The doctor flow doesn't activate the plugin runtime registry, and pre-activation only runs at gateway startup, so after this change an external-plugin heartbeat target with an explicit to and a pinned heartbeat.session that has no store entry now resolves to channel:"none". That makes the deliveryWithoutSession.channel !== "none" short-circuit at doctor-heartbeat-session-target.ts:99 fall through and emit a false "replies are dropped silently" warning that doesn't match real runtime behavior (where startup pre-activation would have loaded the plugin). Bundled channels aren't affected; only external plugin channels are. Consider threading a caller-controlled flag through resolveHeartbeatDeliveryTarget (wake path opts out of bootstrap, doctor keeps it) rather than hardcoding allowBootstrap: false for every caller.

  2. src/infra/outbound/heartbeat-pre-activate.test.ts has no assertions — every case is a does-not-throw smoke test (a few even say "No assertion needed"). This is the module the fix depends on to not drop config-declared external targets, and the interesting logic (isExternalPluginTarget skipping standard/none/last, the per-agent target ?? defaults.target merge, and the dedup set) is exactly what's unverified. A spy on resolveOutboundChannelPlugin asserting it's invoked with allowBootstrap: true for the expected external targets and NOT invoked for standard/none/last/heartbeat-less entries would actually pin the behavior.

  3. Question: for a wake that supplies requestedHeartbeat.target naming an external, non-config channel (merged via mergeRequestedHeartbeat: true), the target is neither pre-activated nor bootstrapped on the hot path. The common cron/commitment cases collapse to target:"last" and stay on the preserved bootstrap fallback, so I think this is fine in practice — can you confirm no supported wake source passes an external non-config target here, or add a note that it's intentionally out of scope?

The targets.test.ts changes look good and correctly prove both the no-bootstrap explicit path and the preserved target:"last" bootstrap.

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: L and removed size: M labels Jul 6, 2026
@xialonglee

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review Amir! All three points were spot on:

  1. Doctor regression: Added allowBootstrap?: boolean to resolveHeartbeatDeliveryTarget. Defaults to false (wake hot path stays fast), doctor passes true so it resolves external plugin targets without preactivation.

  2. Test assertions: Rewrote heartbeat-pre-activate.test.ts — it now uses vi.mock("./channel-resolution.js") and asserts resolveOutboundChannelPlugin call count, allowBootstrap: true param, standard-channel skip, dedup, and distinct-target paths. No more no-assertion smoke tests.

  3. Requested override target: Yes, confirmed — cron and manual wakes all collapse to target: "last" through resolveHeartbeatForWake (see mergeRequestedHeartbeat: true + the source === "cron" guard that omits explicit destinations). External non-config targets from requestedHeartbeat only appear if a caller intentionally passes a non-standard override, which doesn't happen from the supported wake sources. Added a preactivation safety net in the wake handler anyway for future callers.

See the latest commit for details. Thanks again!

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 6, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 7, 2026
@xialonglee

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed the [P1] finding from the last review — explicit normalized heartbeat plugin targets now honor caller allowBootstrap and bundled fallback is disabled on the hot path.

Changes (b63f951165):

  1. resolveHeartbeatDeliveryTarget (L217-225): plugin lookup for explicit normalized targets now threads params.allowBootstrap through (isSessionDerived || params.allowBootstrap === true) instead of hardcoding false. Bundled fallback disabled unconditionally.
  2. resolveHeartbeatDeliveryTargetWithSessionRoute (L362-367): bundled fallback also disabled.
  3. +2 regression tests in targets.test.ts exercising the production normalization path where normalizeDeliverableOutboundChannel preserves external plugin ids.

Test results: 145/145 pass across 4 test files.

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 7, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 8, 2026
@clawsweeper clawsweeper Bot removed the rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. label Jul 8, 2026
@steipete

Copy link
Copy Markdown
Contributor

Land-ready maintainer pass complete on exact head 1cb78cba2434eca714d42e0d7774494eee424ae2.

  • Reworked the fix in the shared outbound bootstrap owner: one failed activation per channel/config/registry generation, bounded across interleaved configs, with retries only after a real config or registry reload.
  • Focused Testbox proof: corepack pnpm test src/infra/outbound/channel-bootstrap.runtime.test.ts src/infra/outbound/channel-resolution.test.ts — 34/34 passed.
  • Scoped Testbox changed gate: core and coreTests lanes passed.
  • Disposable Gateway proof: an unavailable external channel activated once, repeated explicit/session-derived resolutions stayed no-target without rescanning, and config plus registry reloads each admitted exactly one new activation (OPENCLAW_PR100377_LIVE_CLEAN_OK).
  • Fresh branch-scoped autoreview: no findings.
  • Exact-head hosted CI: https://github.com/openclaw/openclaw/actions/runs/29145988256 — success.
  • Native review artifacts and hosted prepare gate passed. No known proof gaps for this server-side fix.

Contributor credit is retained in the code commit and changelog. Thank you, @xialonglee.

@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

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

Labels

merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants