Skip to content

refactor(plugins): separate conversation binding approval state - #139984

Merged
steipete merged 1 commit into
mainfrom
steipete/deletion-plugin-binding-state
Sep 6, 2026
Merged

steipete merged 1 commit into
mainfrom
steipete/deletion-plugin-binding-state

Conversation

@steipete

@steipete steipete commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Related: #135868

What Problem This Solves

Plugin conversation binding combines durable approval state, pending request lifetime, and routing in a grandfathered oversized module. This is the maintainer-requested deletion and suppression-debt follow-up to the #135868 split campaign.

Why This Change Was Made

Separate the existing approval store/cache and shared outage-notice state into one lifecycle state module. Remove redundant approval-scope projections, pass typed identity/conversation objects to the private lifecycle logger, and inline its single-use URI encoder wrapper.

The SQLite queries, transaction boundaries, cache representation, global singleton key, and persist-before-cache-publication ordering are unchanged. This is the first of two small splits; the pending-request lifetime owner still needs extraction before the original module can lose its max-lines suppression.

User Impact

No behavior or public API changes. Production shrinks by 25 lines (164 added / 189 removed); tests and tooling are unchanged. Relocated code is included in both sides of that count. Legacy session-key migration remains because it is present in shipped v2026.9.2; history tracks the recognition through e357203.

Evidence

Existing boundary tests protect root/channel/account approval scope, failed SQLite writes before cache publication, overlapping grants, rows outside the cache, duplicate module instances, and lifecycle drains. No tests or assertions were removed.

Validation: 38 focused tests passed across conversation-binding, its SQLite boundary suite, and global-singleton lifecycle tests. Full node scripts/check-changed.mjs exited 0, including core/core-test typechecks, lint, storage guards, all three dead-export scans, and zero runtime import cycles. Independent Codex review against the pinned merge base: scoped-clean through P2. git diff --check passed.

ClawSweeper reviewed exact head f0adcd63b2aba7e74067e5afe6ead1dc9c867b7c: no actionable correctness/security findings and no before-merge or rank-up requests.

@clawsweeper

clawsweeper Bot commented Sep 6, 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.

@steipete
steipete marked this pull request as ready for review September 6, 2026 09:32
@openclaw-barnacle openclaw-barnacle Bot added the maintainer Maintainer-authored PR label Sep 6, 2026
@clawsweeper clawsweeper Bot added P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. 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 6, 2026
@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed September 6, 2026, 5:51 AM ET / 09:51 UTC.

ClawSweeper review

What this changes

Moves conversation-binding approval storage and shared cache state into an internal module and simplifies lifecycle logging without changing user-visible behavior.

Merge readiness

✅ Ready for maintainer review

This remains a useful, bounded cleanup with no actionable correctness or security findings. The extraction is absent from fetched main and the latest release; the previous review’s empty finding list remains appropriate.

Priority: P3
Reviewed head: f0adcd63b2aba7e74067e5afe6ead1dc9c867b7c

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, behavior-preserving extraction with retained boundary coverage and no actionable findings.
Proof confidence 🌊 off-meta tidepool Not applicable: The supplied MEMBER-authored refactor is exempt from ordinary contributor runtime proof; approval persistence and lifecycle behavior are unchanged, with no material authority change requiring additional proof.
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-authored refactor is exempt from ordinary contributor runtime proof; approval persistence and lifecycle behavior are unchanged, with no material authority change requiring additional proof.
Evidence reviewed 7 items Pinned introduced change: The complete base-to-head diff relocates existing persistence and singleton code, removes redundant field projections, and preserves logger field values and URI encoding. It introduces no schema, dependency, public SDK, configuration, or workflow change.
Persistence and lifecycle invariants: The extracted owner retains the global symbol, in-place lifecycle reset, normalized root/channel/account lookup, targeted SQLite upsert, and persistence before cache publication. The singleton helper continues sharing the same object across module instances.
Production callers and implementation boundary: Approval requests, ownership checks, binding creation, resolution callbacks, and fallback notices retain their existing paths. The moved code depends on OpenClaw-owned storage and lifecycle helpers; unchanged legacy session prefixes do not establish a Codex runtime dependency.
Findings None None.
Security None None.

How this fits together

Conversation bindings let approved plugins handle subsequent messages in a channel conversation. This subsystem checks durable approvals scoped to plugin root, channel, and account, then either requests approval or creates the binding.

flowchart TD
  A[Plugin binding request] --> B[Check existing binding]
  B --> C[Approval store and cache]
  C --> D{Approval available?}
  D -->|Yes| E[Create conversation binding]
  D -->|No| F[Ask user for approval]
  F -->|Always allow| C
  E --> G[Route subsequent messages]
Loading

Before merge

None.

Agent review details

Security

None.

PR surface

Source -25. Total -25 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 2 164 189 -25
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 164 189 -25

Review metrics

None.

Technical review

Best possible solution:

Keep approval persistence and cache lifecycle together while preserving the existing binding entrypoints, stored representation, and authorization scope.

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

Not applicable: this PR reorganizes existing code rather than reporting a runtime defect; source inspection found no introduced failing path.

Is this the best way to solve the issue?

Yes: extracting the existing state owner is a narrow way to reduce module complexity without introducing parallel persistence or changing the public API.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P3: This is internal maintenance that preserves existing behavior and public contracts.
  • 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-authored refactor is exempt from ordinary contributor runtime proof; approval persistence and lifecycle behavior are unchanged, with no material authority change requiring additional proof.

Evidence

What I checked:

  • Pinned introduced change: The complete base-to-head diff relocates existing persistence and singleton code, removes redundant field projections, and preserves logger field values and URI encoding. It introduces no schema, dependency, public SDK, configuration, or workflow change. (src/plugins/conversation-binding-state.ts:32, f0adcd63b2ab)
  • Persistence and lifecycle invariants: The extracted owner retains the global symbol, in-place lifecycle reset, normalized root/channel/account lookup, targeted SQLite upsert, and persistence before cache publication. The singleton helper continues sharing the same object across module instances. (src/plugins/conversation-binding-state.ts:127, f0adcd63b2ab)
  • Production callers and implementation boundary: Approval requests, ownership checks, binding creation, resolution callbacks, and fallback notices retain their existing paths. The moved code depends on OpenClaw-owned storage and lifecycle helpers; unchanged legacy session prefixes do not establish a Codex runtime dependency. (src/plugins/conversation-binding.ts:586, f0adcd63b2ab)
  • Retained boundary coverage: The SQLite suite exercises approval, account isolation, restart persistence, and owner-scoped detach through the production binding service. Additional inspected tests cover failed writes, overlapping grants, external rows, duplicate module instances, and lifecycle drains. Tests were inspected, not executed during this read-only review. (src/plugins/conversation-binding.sqlite.test.ts:61, f0adcd63b2ab)
  • Current main and release comparison: Fetched main has no conversation-binding-state.ts, and its conversation-binding.ts matches the pinned base. Inspection of v2026.9.2 likewise found approval loading and singleton state still in the original module. The proposed extraction therefore remains distinct work. (src/plugins/conversation-binding.ts, 2dbbb33887ae)
  • Feature-history routing: Current-main history identifies Peter Steinberger’s recent binding ownership and lifecycle work, Masato Hoshino’s persist-before-cache change, and Vincent Koc’s SQLite migration. Raw commit records were inspected, but historical blob retrieval prevented exact parent-patch verification; these are routing candidates without introduction attribution. (src/plugins/conversation-binding.ts, 2dbbb33887ae)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Masato Hoshino: 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 (1 earlier review cycle)
  • reviewed 2026-09-06T09:37:51.809Z sha f0adcd6 :: needs maintainer review before merge. :: none

@steipete
steipete merged commit 69327a2 into main Sep 6, 2026
254 checks passed
@steipete
steipete deleted the steipete/deletion-plugin-binding-state branch September 6, 2026 09:52
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

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

Labels

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: M 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