Skip to content

refactor(discord): share prepared binding expiry selection - #140643

Merged
steipete merged 1 commit into
mainfrom
steipete/dedup-channels-bindings-0906
Sep 7, 2026
Merged

steipete merged 1 commit into
mainfrom
steipete/dedup-channels-bindings-0906

Conversation

@steipete

@steipete steipete commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

What Problem This Solves

Discord computed binding deadlines independently in its session adapter and expiry sweeper, duplicating the shared lifecycle's earliest-deadline selection. Keeping those paths separate makes lifecycle reporting and removal reasons easier to diverge.

Related: #140073, #129801, #138007. All three diffs were inspected before this change. Their configured-binding provenance, native Discord reply routing, and Feishu live-config refresh remain with their respective owners.

Why This Change Was Made

The shared binding lifecycle now selects prepared expiry candidates. Discord prepares its effective durations and guarded timestamps once for both adapter projection and sweeping. Idle expiration continues to win ties. Native timestamp validation and metadata projection remain with their channel owners: Discord's positive finite timestamp rules differ from the standard lifecycle's binding-time clamp.

User Impact

No user-visible behavior change. Binding identity, metadata precedence, persistence, expiration, and asynchronous sweeper fencing remain unchanged. Existing exports remain available.

Evidence

  • node scripts/run-vitest.mjs src/shared/thread-binding-lifecycle.test.ts extensions/discord/src/monitor/thread-bindings: 57 tests passed across five files, including async sweeper fencing, same-target metadata preservation, legacy timestamps, non-finite overrides, disabled limits, and expiry ties.
  • Independent Codex autoreview: zero P0–P2 findings. The fresh-main rebase is patch-identical, verified with git range-diff.
  • node scripts/check-changed.mjs plus targeted continuation: all four typecheck lanes, core lint, SDK/doctor/dependency guards, export scans, and remaining architecture guards passed. Local extension lint encountered the documented nested-checkout Declaration input escapes checkout limitation; no ancestor install or guard was changed.
  • pnpm build: passed, including all 152 public SDK subpaths and 90 external plugins. A native Node probe imported the built openclaw/plugin-sdk/thread-bindings-session-runtime helper and verified idle-expiry tie behavior.
  • Exact-head hosted CI passed on 5e3dbbc8835869c077c6a59be37f30443fd9e5b1: https://github.com/openclaw/openclaw/actions/runs/34077676325
  • The hosted extension-package-boundary job passed: https://github.com/openclaw/openclaw/actions/runs/34077676325/job/101606977476
  • Production delta: -22 lines; tests: +54 lines; documentation: +8 lines.
  • Live-channel gap: no live Discord transport was exercised. Synthetic adapter/lifecycle tests provide boundary proof; no live Gateway was touched.

@clawsweeper

clawsweeper Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord size: S maintainer Maintainer-authored PR labels Sep 7, 2026
@clawsweeper clawsweeper Bot added P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. 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 Sep 7, 2026
@steipete
steipete marked this pull request as ready for review September 7, 2026 02:27
@clawsweeper

clawsweeper Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed September 6, 2026, 10:57 PM ET / September 7, 2026, 02:57 UTC.

ClawSweeper review

What this changes

Discord shares expiration selection between session-binding reporting and automatic cleanup while preserving its timestamp rules, timeout settings, and idle-expiration tie precedence.

Merge readiness

✅ Ready for maintainer review

Keep open: this is a focused, maintainer-authored refactor that remains distinct from current main. No actionable correctness or security defect was found.

Priority: P3
Reviewed head: 5e3dbbc8835869c077c6a59be37f30443fd9e5b1

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, behavior-preserving extraction with relevant compatibility coverage and no actionable findings.
Proof confidence 🌊 off-meta tidepool Not applicable: The supplied MEMBER status exempts this internal refactor from contributor live-proof requirements, and no material authority change triggers an exception. Reported lifecycle tests and the built-SDK tie probe support the changed selector; live Discord transport was explicitly not exercised.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The supplied MEMBER status exempts this internal refactor from contributor live-proof requirements, and no material authority change triggers an exception. Reported lifecycle tests and the built-SDK tie probe support the changed selector; live Discord transport was explicitly not exercised.
Evidence reviewed 9 items Pinned change and repository identity: The origin URL identifies openclaw/openclaw. The host verified the introduced delta from 68c589a to the checked-out head; review used that delta rather than attributing current-main drift to the PR.
Discord normalization preserves the selection invariant: Manager defaults reject non-finite durations before use; record overrides retain finite-number checks. The extracted timestamp helper preserves positive finite timestamps and disabled limits, so selecting the earliest deadline before checking the clock preserves the previous sweeper behavior.
Lifecycle and asynchronous fencing: The manager still rereads each binding before expiration decisions and checks binding identity after awaited channel probes. The adapter retains binding identity and metadata precedence. No authorization, persistence format, or routing-precedence change is introduced.
Findings None None.
Security None None.

How this fits together

Discord thread bindings connect conversations to agent sessions. Their timestamps and timeout settings determine the expiration reported to session services and when the background sweeper removes a binding.

flowchart TD
  A[Discord binding records] --> C[Prepare validated deadlines]
  B[Timeout defaults and overrides] --> C
  C --> D[Select earliest deadline]
  D --> E[Report session binding expiration]
  D --> F[Background expiration check]
  F --> G[Remove expired binding and send farewell]
Loading

Before merge

None.

Agent review details

Security

None.

PR surface

Source -22, Tests +54, Docs +8. Total +40 across 7 files.

View PR surface stats
Area Files Added Removed Net
Source 5 59 81 -22
Tests 1 55 1 +54
Docs 1 8 0 +8
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 7 122 82 +40

Review metrics

Metric Value Why it matters
Public SDK contract 1 additive export; 0 existing exports removed The prepared-deadline selector is documented separately from the existing timestamp-normalizing lifecycle API.

Technical review

Best possible solution:

Keep one shared deadline selector while leaving timestamp validation and timeout defaults with each plugin.

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

Not applicable: this PR addresses duplicated implementation rather than a reported runtime failure; source inspection confirms the separate selection paths.

Is this the best way to solve the issue?

Yes: extracting only candidate selection avoids imposing the standard lifecycle's binding-time clamp on Discord and preserves the existing public APIs.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against acba0c658dc9.

Labels

Label justifications:

  • P3: This is bounded internal deduplication with no intended user-visible behavior change.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The supplied MEMBER status exempts this internal refactor from contributor live-proof requirements, and no material authority change triggers an exception. Reported lifecycle tests and the built-SDK tie probe support the changed selector; live Discord transport was explicitly not exercised.

Evidence

What I checked:

  • Pinned change and repository identity: The origin URL identifies openclaw/openclaw. The host verified the introduced delta from 68c589a to the checked-out head; review used that delta rather than attributing current-main drift to the PR. (5e3dbbc88358)
  • Discord normalization preserves the selection invariant: Manager defaults reject non-finite durations before use; record overrides retain finite-number checks. The extracted timestamp helper preserves positive finite timestamps and disabled limits, so selecting the earliest deadline before checking the clock preserves the previous sweeper behavior. (extensions/discord/src/monitor/thread-bindings.state.ts:211, 5e3dbbc88358)
  • Lifecycle and asynchronous fencing: The manager still rereads each binding before expiration decisions and checks binding identity after awaited channel probes. The adapter retains binding identity and metadata precedence. No authorization, persistence format, or routing-precedence change is introduced. (extensions/discord/src/monitor/thread-bindings.manager.ts:125, 5e3dbbc88358)
  • Documented additive SDK contract: The new export selects prepared deadlines while the existing lifecycle API retains its timestamp normalization. The maintainer-authored body explains this distinction, and the documentation assigns validation and duration defaults to callers. Existing exports remain available; Telegram and Matrix continue using the unchanged standard lifecycle contract. Public docs: docs/plugins/sdk-channel-plugins.md. (docs/plugins/sdk-channel-plugins.md:493, 5e3dbbc88358)
  • Current main still has separate selection: Current main retains inline selection in the shared lifecycle and Discord's separate expiration-candidate selection. The reviewed extraction is therefore still distinct work. (src/shared/thread-binding-lifecycle.ts:43, acba0c658dc9)
  • Latest release comparison: The supplied v2026.9.2 release commit retains Discord's independent expiration-candidate array and sorting; this refactor is not present there. (extensions/discord/src/monitor/thread-bindings.manager.ts:137, 3928bad9badf)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Vincent Koc: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (2 earlier review cycles)
  • reviewed 2026-09-07T02:26:21.914Z sha 6f3250ab1f7c3ee2045fd517f557060ca5310a44 :: blocked before merge. :: none
  • reviewed 2026-09-07T02:43:07.303Z sha 6f3250ab1f7c3ee2045fd517f557060ca5310a44 :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Sep 7, 2026
Keep Discord timestamp validation and idle-expiry tie precedence while sharing
candidate selection with the binding lifecycle owner.

Proof: node scripts/run-vitest.mjs src/shared/thread-binding-lifecycle.test.ts extensions/discord/src/monitor/thread-bindings
57 focused tests passed; independent review has no actionable findings.
@steipete
steipete force-pushed the steipete/dedup-channels-bindings-0906 branch from 6f3250a to 5e3dbbc Compare September 7, 2026 02:51
@steipete
steipete merged commit 96dd4b8 into main Sep 7, 2026
185 of 187 checks passed
@steipete
steipete deleted the steipete/dedup-channels-bindings-0906 branch September 7, 2026 03:05
@steipete

steipete commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 7, 2026
…140643)

Keep Discord timestamp validation and idle-expiry tie precedence while sharing
candidate selection with the binding lifecycle owner.

Proof: node scripts/run-vitest.mjs src/shared/thread-binding-lifecycle.test.ts extensions/discord/src/monitor/thread-bindings
57 focused tests passed; independent review has no actionable findings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord docs Improvements or additions to documentation maintainer Maintainer-authored PR P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant