Skip to content

fix(heartbeat): bound pending final delivery replay#85770

Closed
NianJiuZst wants to merge 1 commit into
openclaw:mainfrom
NianJiuZst:codex/fix-85743-pending-final-delivery-heartbeat-bounds
Closed

fix(heartbeat): bound pending final delivery replay#85770
NianJiuZst wants to merge 1 commit into
openclaw:mainfrom
NianJiuZst:codex/fix-85743-pending-final-delivery-heartbeat-bounds

Conversation

@NianJiuZst

@NianJiuZst NianJiuZst commented May 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: heartbeat replay kept re-sending orphaned pendingFinalDeliveryText forever because the replay branch had no terminal retry or age bound.
  • Solution: add a heartbeat-only replay give-up gate that clears stale pending final delivery after 10 replay attempts or 24 hours.
  • What changed: src/auto-reply/reply/get-reply.ts now shares one clear helper, logs retry-limit / expiry give-up reasons, and skips replay once the bound trips; src/auto-reply/reply/get-reply.fast-path.test.ts now locks both bounds in with regression coverage.
  • What did NOT change (scope boundary): this does not alter the existing clear-on-success dispatch path, restart recovery flow, or subagent pending-final-delivery lifecycle semantics.

Motivation

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Real behavior proof (required for external PRs)

  • Behavior addressed: stale heartbeat pending-final-delivery replay now stops after a bounded number of attempts or once the pending payload ages past the TTL instead of replaying forever.
  • Real environment tested: local macOS source checkout, Node v24.14.1, repo runtime loaded through node --import tsx, real sessions.json persistence under a temp directory.
  • Exact steps or command run after this patch:
node --import tsx --input-type=module <<'EOF'
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { getReplyFromConfig } from './src/auto-reply/reply/get-reply.ts';

const home = await fs.mkdtemp(path.join(os.tmpdir(), 'openclaw-85743-proof-'));
const storePath = path.join(home, 'sessions.json');
const sessionKey = 'agent:main:telegram:123';
await fs.writeFile(
  storePath,
  JSON.stringify({
    [sessionKey]: {
      sessionId: 'pending-limit',
      updatedAt: Date.now(),
      pendingFinalDelivery: true,
      pendingFinalDeliveryText: 'HEARTBEAT_OK short',
      pendingFinalDeliveryCreatedAt: Date.now(),
      pendingFinalDeliveryAttemptCount: 10,
      pendingFinalDeliveryLastError: null,
    },
  }),
  'utf8',
);
const cfg = {
  agents: {
    defaults: {
      model: 'openai/gpt-5.5',
      workspace: home,
      heartbeat: { ackMaxChars: 0 },
    },
  },
  session: { store: storePath },
};
const ctx = {
  Provider: 'telegram',
  Surface: 'telegram',
  ChatType: 'direct',
  Body: 'heartbeat',
  BodyForAgent: 'heartbeat',
  RawBody: 'heartbeat',
  CommandBody: 'heartbeat',
  SessionKey: sessionKey,
  From: 'telegram:user:42',
  To: 'telegram:123',
  Timestamp: 1710000000000,
};
const reply = await getReplyFromConfig(ctx, { isHeartbeat: true }, cfg);
const stored = JSON.parse(await fs.readFile(storePath, 'utf8'))[sessionKey];
console.log(JSON.stringify({ reply, stored }, null, 2));
EOF
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):
[warn] Clearing stale heartbeat pending final delivery (retry-limit) after 11 attempts ageMs=6996 for session agent:main:telegram:123.

and the persisted session record printed with pendingFinalDelivery, pendingFinalDeliveryText, and pendingFinalDeliveryAttemptCount cleared.

  • Observed result after fix: once the replay branch computed the 11th attempt, it logged the give-up reason, cleared the durable pending-final-delivery fields, and did not replay short again.
  • What was not tested: a real remote Crabbox/Testbox pnpm check:changed run is still blocked in this environment because no usable crabbox binary is installed locally; only focused local tests and the local persisted-session proof above were run.
  • Before evidence (optional but encouraged): before this patch, the same heartbeat replay branch incremented pendingFinalDeliveryAttemptCount, rewrote the replay text, and returned the cached replay payload without any retry-limit or TTL gate.

Root Cause (if applicable)

  • Root cause: the heartbeat replay branch in src/auto-reply/reply/get-reply.ts incremented pendingFinalDeliveryAttemptCount and returned the replay text every tick, but never checked whether the replay had already been retried too many times or had gone stale by age.
  • Missing detection / guardrail: there was no heartbeat-side terminal condition comparable to the existing retry-limit / expiry give-up vocabulary already used by the subagent pending-final-delivery lifecycle.
  • Contributing context (if known): durable pending final delivery was introduced in c240e718e91 and later replay cleanups only handled ack-only stripping and adjacent narrower causes, not this general orphan-session fail-safe.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/auto-reply/reply/get-reply.fast-path.test.ts
  • Scenario the test should lock in: heartbeat replay clears stale pending-final-delivery state once retry count exceeds the cap, and also clears it when the pending payload is older than the TTL.
  • Why this is the smallest reliable guardrail: the bug lives entirely inside the heartbeat replay branch’s state transition logic, so a focused store-backed getReplyFromConfig test exercises the exact persisted-session mutation without needing a broader dispatcher harness.
  • Existing test that already covers this (if any): existing adjacent tests already covered ack-only clear and substantive replay, but not terminal cleanup after repeated or old replays.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

Heartbeat sessions no longer replay stale pending final delivery forever. Once a pending heartbeat replay exceeds 10 attempts or stays pending for more than 24 hours, OpenClaw drops the stale replay state and proceeds instead of re-sending the same cached alert on every heartbeat tick.

Diagram (if applicable)

Before:
[heartbeat tick] -> [pendingFinalDelivery replay branch] -> [increment attempt count] -> [return stale replay forever]

After:
[heartbeat tick] -> [pendingFinalDelivery replay branch] -> [check attempts + age]
               -> [under bound] -> [replay once more]
               -> [over bound] -> [clear pending final delivery] -> [continue without stale replay]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node v24.14.1 local source checkout
  • Model/provider: not required for the focused replay-state tests; local runtime proof entered the heartbeat replay path before any successful model call
  • Integration/channel (if any): Telegram-shaped heartbeat session metadata
  • Relevant config (redacted): agents.defaults.model=openai/gpt-5.5, agents.defaults.heartbeat.ackMaxChars=0, temp session.store

Steps

  1. Seed sessions.json with a main-session entry whose pendingFinalDelivery is true, pendingFinalDeliveryText is substantive (HEARTBEAT_OK short), and pendingFinalDeliveryAttemptCount is already 10 or whose pendingFinalDeliveryCreatedAt is older than 24 hours.
  2. Invoke getReplyFromConfig(..., { isHeartbeat: true }, cfg) against that store-backed session.
  3. Inspect the persisted session entry after the heartbeat replay branch runs.

Expected

  • A stale replay should be cleared instead of replayed again.
  • The durable pending-final-delivery fields should be unset.

Actual

  • The branch logs a retry-limit or expiry warning, clears the stale pending-final-delivery fields, and does not return the stale replay text.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: retry-limit cleanup in the heartbeat replay branch, TTL cleanup in the same branch, existing ack-only clear behavior, existing substantive replay behavior, adjacent e2e durable-pending-final-delivery capture behavior, and heartbeat busy-lane skip behavior.
  • Edge cases checked: ack-only heartbeat payloads still clear immediately; short substantive heartbeat payloads still replay when below the new bounds; sanitize-before-replay still preserves visible payload text.
  • What you did not verify: remote Linux/Testbox broad changed gate proof is still blocked by the missing local crabbox binary in this environment.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: a legitimately recoverable pending final delivery that stays orphaned past 10 heartbeats or 24 hours will now be dropped instead of replayed indefinitely.
    • Mitigation: the bound is heartbeat-only, preserves normal replay behavior below the threshold, and is intentionally conservative to stop proven user-visible duplication failures.
  • Risk: future durable-delivery intent migration might want a shared clear helper across more replay surfaces.
    • Mitigation: this patch keeps the new helper local to the current heartbeat replay owner boundary and does not pre-empt the later intent-store migration.

@openclaw-barnacle openclaw-barnacle Bot added size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed June 24, 2026, 7:48 AM ET / 11:48 UTC.

Summary
The PR adds heartbeat-only retry-count and age bounds for stale pending-final-delivery cleanup in get-reply.ts plus focused fast-path regression tests.

PR surface: Source +43, Tests +80. Total +123 across 2 files.

Reproducibility: yes. at source level. Current source and tests show non-ack heartbeat pending-final state is preserved without a cutoff, while the PR head can return cached replay text before the cutoff.

Review metrics: 1 noteworthy metric.

  • Pending-state clear coverage: 7 of 8 current fields cleared. The PR changes durable pending-final cleanup, and leaving one field behind keeps stale recovery metadata attached to the session.

Stored data model
Persistent data-model change detected: persistent cache schema: src/auto-reply/reply/get-reply.fast-path.test.ts, serialized state: src/auto-reply/reply/get-reply.fast-path.test.ts. Migration or upgrade compatibility proof is recorded; maintainers should verify it before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #85743
Summary: This PR is the open closing candidate for the canonical orphan heartbeat pending-final TTL/attempt fail-safe issue; adjacent PRs handle narrower send-success cleanup or broader not-ready recovery designs.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦞 diamond lobster
Patch quality: 🧂 unranked krab
Result: blocked by patch quality or review findings.

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

Rank-up moves:

  • Remove direct heartbeat cached-text replay for under-bound substantive pending finals.
  • Clear pendingFinalDeliveryIntentId with the other pending-final fields.
  • [P2] Refresh the focused terminal proof after the repair.

Risk before merge

  • [P1] As submitted, the under-bound path can send cached user-facing final text from heartbeat before the new cutoff trips.
  • [P2] The retry/TTL abandonment threshold is a session-state and message-delivery policy choice because it can drop a final reply that might still be recoverable.
  • [P1] The branch is stale against a shared getReplyFromConfig surface and related open pending-final PRs, so it needs rebase and re-review before merge.

Maintainer options:

  1. Repair The Current Branch (recommended)
    Rebase onto current main, preserve heartbeat no-direct-replay for under-bound non-ack pending finals, and clear the full pending-final field set only when the cutoff fires.
  2. Accept Bounded Replay Policy
    Maintainers could intentionally allow bounded heartbeat replay before abandonment, but that needs explicit delivery-policy approval and route-safety proof.
  3. Pause For A Replacement
    If the branch cannot be reconciled cleanly, keep the canonical issue open and replace this PR with a narrower current-main implementation.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Rebase onto current main; preserve heartbeat no-direct-replay by not returning cached user-facing pending text; clear every pendingFinalDelivery* field including pendingFinalDeliveryIntentId when retry/TTL cutoff fires; update focused tests for under-bound no-replay, retry-limit clear, TTL clear, and full-field cleanup.

Next step before merge

  • [P2] A narrow mechanical repair can preserve the useful cutoff while adapting it to current main's no-replay invariant and full pending-field cleanup.

Security
Cleared: The diff only changes TypeScript session replay logic and tests; it adds no dependencies, permissions, secret handling, network calls, CI, or package execution surface.

Review findings

  • [P1] Preserve heartbeat no-replay behavior — src/auto-reply/reply/get-reply.ts:519
  • [P2] Clear the current pending-final intent field — src/auto-reply/reply/get-reply.ts:440-464
Review details

Best possible solution:

Land a current-main-compatible cutoff that clears stale over-bound pending-final state, never directly replays cached user-facing final text from heartbeat, and clears every current pending-final field together.

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

Yes at source level. Current source and tests show non-ack heartbeat pending-final state is preserved without a cutoff, while the PR head can return cached replay text before the cutoff.

Is this the best way to solve the issue?

No, not as submitted. The cutoff direction matches the canonical issue, but the implementation must preserve current no-direct-replay behavior and clear the full pending-final state shape.

Full review comments:

  • [P1] Preserve heartbeat no-replay behavior — src/auto-reply/reply/get-reply.ts:519
    Current main intentionally does not return substantive pending final text from the heartbeat path, and the fast-path tests assert that non-ack pending state remains pending. This under-bound branch returns cached replayText, so a stale user-facing final can be delivered by heartbeat again before the new cutoff trips.
    Confidence: 0.9
  • [P2] Clear the current pending-final intent field — src/auto-reply/reply/get-reply.ts:440-464
    The new clear helper omits pendingFinalDeliveryIntentId, but current session state and dispatch-success cleanup treat that as part of the durable pending-final field set. Abandoning stale pending text while leaving the send-intent metadata behind keeps stale recovery state attached to the session.
    Confidence: 0.84

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P1: The PR targets and can affect a high-impact heartbeat/session-state bug that can duplicate, suppress, or misroute user-visible message delivery.
  • merge-risk: 🚨 session-state: The diff adds terminal clearing for persisted pendingFinalDelivery state and currently leaves one current pending-final field behind.
  • merge-risk: 🚨 message-delivery: The under-bound branch can send cached final text from heartbeat before the new cutoff clears it.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦞 diamond lobster and patch quality is 🧂 unranked krab.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes terminal proof against a real temporary sessions.json store showing stale retry-limit cleanup; a repaired head should refresh proof after behavior changes.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal proof against a real temporary sessions.json store showing stale retry-limit cleanup; a repaired head should refresh proof after behavior changes.
Evidence reviewed

PR surface:

Source +43, Tests +80. Total +123 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 92 49 +43
Tests 1 80 0 +80
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 172 49 +123

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs src/auto-reply/reply/get-reply.fast-path.test.ts.
  • [P1] node scripts/run-vitest.mjs src/infra/heartbeat-runner.skips-busy-session-lane.test.ts.
  • [P1] node scripts/run-vitest.mjs src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts.
  • [P1] git diff --check.

What I checked:

  • Repository policy: Root AGENTS.md was read fully; its review policy treats session state and message delivery changes as compatibility/upgrade-sensitive and requires current-source, tests, history, and related-item review. (AGENTS.md:1, 1069c60e1e25)
  • Current main behavior: Current main allows heartbeat to clear ack-only pending state but does not directly return non-ack pending-final text through heartbeat. (src/auto-reply/reply/get-reply.ts:520, 1069c60e1e25)
  • Current tests protect no-replay: The current fast-path tests assert non-ack heartbeat pending delivery remains pending, returns the normal reply, and does not increment a replay attempt count. (src/auto-reply/reply/get-reply.fast-path.test.ts:300, 1069c60e1e25)
  • PR head replays cached text: The PR head returns { text: replayText } for under-bound non-ack heartbeat pending delivery, which conflicts with current main's no-direct-replay invariant. (src/auto-reply/reply/get-reply.ts:519, 887aa2c3bb0d)
  • PR clear helper omits intent id: The PR clear helper clears seven pending-final fields, while the current canonical dispatch success cleanup also clears pendingFinalDeliveryIntentId. (src/auto-reply/reply/get-reply.ts:440, 887aa2c3bb0d)
  • Latest release check: The latest release tag has the same no-direct-heartbeat-replay behavior and still lacks a non-ack retry/TTL cleanup, so the remaining bug is not fully shipped-fixed. (src/auto-reply/reply/get-reply.ts:510, aa69b12d0086)

Likely related people:

  • kesslerio: Authored the merged heartbeat stale-final suppression PR that defines the current no-direct-replay invariant this PR must preserve. (role: recent area contributor; confidence: high; commits: d00e764e6655, 5c5b13dd4743, e1d6f32aef81; files: src/auto-reply/reply/get-reply.ts, src/auto-reply/reply/get-reply.fast-path.test.ts, src/infra/heartbeat-runner.ts)
  • steipete: Merged the heartbeat stale-final suppression PR and authored the final commit on that branch, so they are relevant to the accepted behavior boundary. (role: merger; confidence: medium; commits: d00e764e6655, e1d6f32aef81; files: src/auto-reply/reply/get-reply.ts, src/infra/heartbeat-runner.ts)
  • MertBasar0: The durable main-session pending-final-delivery machinery appears to date to the merged durable delivery work. (role: introduced behavior; confidence: high; commits: c240e718e91e, 7a2c1fba85c3, 98dc525d5975; files: src/auto-reply/reply/get-reply.ts, src/auto-reply/reply/agent-runner.ts, src/config/sessions/types.ts)
  • amknight: Authored the merged dispatch success cleanup that defines the current full pending-final clear shape, including pendingFinalDeliveryIntentId. (role: adjacent owner; confidence: medium; commits: eab22a911a2d, 14bdcd522e11; files: src/auto-reply/reply/dispatch-from-config.ts, src/auto-reply/reply/dispatch-from-config.reply-dispatch.test.ts)
  • agocs: Owns the open send-success cleanup PR for the same pending-final state family and has current proof around full-field cleanup and ownership gating. (role: recent adjacent contributor; confidence: medium; commits: 675dcd8ab6e6, fb37c771f597; files: src/infra/heartbeat-runner.ts, src/infra/heartbeat-runner.clears-pending-final-delivery.test.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.

@clawsweeper clawsweeper Bot added 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. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Velvet Diff Drake

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: sparkles near resolved comments.
Image traits: location diff observatory; accessory commit compass; palette moonlit blue and soft silver; mood mischievous; pose nestled inside a glowing shell; shell starlit enamel shell; lighting soft underwater shimmer; background subtle branch markers.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Velvet Diff Drake in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@BingqingLyu

This comment was marked as spam.

@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: 🐚 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. labels Jun 15, 2026
@NianJiuZst NianJiuZst closed this Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pendingFinalDelivery heartbeat replay loops forever — no attempt cap or TTL on orphan sessions

2 participants