Skip to content

fix(plugins): retain plugin tool registry after replacement#82562

Merged
vincentkoc merged 5 commits into
openclaw:mainfrom
luoyanglang:wolf/plugin-tool-registry-retention
Jun 24, 2026
Merged

fix(plugins): retain plugin tool registry after replacement#82562
vincentkoc merged 5 commits into
openclaw:mainfrom
luoyanglang:wolf/plugin-tool-registry-retention

Conversation

@luoyanglang

@luoyanglang luoyanglang commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: cached descriptor-backed plugin tools can lose their runtime registry after the active registry is replaced, then fail with plugin tool runtime missing.
  • Why it matters: bug(plugins): plugin tools intermittently unavailable in sub-agent sessions despite contracts.tools and compiled dist (regression from #56208) #80847 reports contracted plugin tools becoming unavailable in sub-agent sessions after a few successful calls, with current-main confirmation of this resolver path.
  • What changed: when a forced cold tool-discovery load finds the scoped plugin tools, keep that registry active so later cached descriptor executions reuse the live runtime instead of falling back to an incomplete replacement registry.
  • What did NOT change (scope boundary): this does not broaden plugin allowlists, tool availability, or normal plugin loading; it only retains a successful scoped tool-discovery registry.

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 or issue addressed: cached plugin tool descriptors continue executing after active runtime registry replacement instead of failing with plugin tool runtime missing.

  • Real environment tested: Linux x86_64 dev executor, Node v22.22.2, local OpenClaw runtime harness with a real config-path plugin loaded through resolvePluginTools().

  • Exact steps or command run after this patch:

    • node --import tsx --input-type=module local runtime harness: create a config-path plugin with contracts.tools, resolve/capture cached plugin descriptors, replace the active registry with an incomplete registry for the same plugin id plus an unrelated live tool, then execute the cached descriptor twice.
    • OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts --testNamePattern 'retains cold-loaded plugin tools'
    • OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/active-runtime-registry.test.ts src/plugins/runtime.channel-pin.test.ts
    • pnpm check:changed
  • Evidence after fix: copied live terminal output from the local OpenClaw runtime harness shows the cached descriptor executing twice after incomplete active registry replacement while unrelated active registry tools survive; targeted regression tests, related plugin registry tests, and pnpm check:changed also passed locally.

    Live terminal output from a local OpenClaw runtime harness after this patch:

    openclaw #80847 local runtime proof
    node=v22.22.2 repo=openclaw plugin=cache-live-proof tool=cache_live_tool
    plugin_file=file:///tmp/openclaw-80847-live-DR2not/plugin/index.cjs
    resolved_initial_tools=cache_live_tool
    resolved_cached_tools=cache_live_tool
    active_registry_after_replacement_tools=1
    active_registry_after_replacement_owners=unrelated-live
    execute_after_replacement_1=live-runtime-ok-1
    active_registry_after_first_execute_tools=1
    active_registry_after_first_execute_owners=unrelated-live
    execute_after_replacement_2=live-runtime-ok-2
    active_registry_after_second_execute_tools=1
    active_registry_after_second_execute_owners=unrelated-live
    result=PASS cached descriptor survived incomplete active registry replacement without replacing unrelated active registry tools
    
  • Observed result after fix: first cached descriptor execution returned live-runtime-ok-1; the unrelated active registry owner remained unrelated-live after both executions; the second execution returned live-runtime-ok-2 using the retained scoped recovery registry without replacing global active state.

  • What was not tested: the reporter's private lossless-claw plugin and live five-minute sub-agent archival loop were not available here. Crabbox CLI was installed locally, but remote AWS Crabbox proof was blocked by missing local Crabbox/AWS auth (broker=- auth=missing; crabbox doctor failed at AWS credentials), so no remote Crabbox run is claimed.

  • Before evidence: the new regression failed before the fix with plugin tool runtime unavailable (cache-lifecycle-test): cached_lifecycle_tool on the second cached descriptor execution.

Root Cause (if applicable)

  • Root cause: resolvePluginToolRegistry() forced a cold standalone load when an active/channel registry existed but did not cover the requested plugin tools, but that successful cold-loaded registry was not retained for later cached descriptor executions.
  • Missing detection / guardrail: existing cached descriptor tests did not simulate active registry replacement followed by repeated cached tool execution.
  • Contributing context (if known): recent registry compatibility hardening made partial registry reuse stricter, which is correct, but the recovery cold-load path was ephemeral.

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/plugins/tools.optional.test.ts
  • Scenario the test should lock in: cached plugin tool descriptors execute successfully after the active registry is replaced by an incomplete registry for the same plugin id.
  • Why this is the smallest reliable guardrail: it directly exercises the resolver/cached descriptor path that throws the reported error without needing the reporter's private plugin.
  • Existing test that already covers this (if any): none.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

Contracted plugin tools remain available across registry replacement/sub-agent lifecycle changes instead of intermittently failing until gateway restart.

Diagram (if applicable)

Before:
cached descriptor -> incomplete active registry -> one-off cold load -> later execution fails

After:
cached descriptor -> incomplete active registry -> scoped cold load retained -> later execution succeeds

Security Impact (required)

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

Repro + Verification

Environment

  • OS: Linux x86_64
  • Runtime/container: local Node/Vitest checkout
  • Model/provider: N/A
  • Integration/channel (if any): plugin tool runtime
  • Relevant config (redacted): default test plugin config

Steps

  1. Resolve plugin tools once to seed cached descriptors.
  2. Replace the active registry with an incomplete registry that still declares the same plugin id.
  3. Execute the cached descriptor tool twice.

Expected

  • Both executions succeed; the first recovery cold-load is retained for the second execution.

Actual

  • Before this patch, the second execution rejected with plugin tool runtime unavailable.
  • After this patch, both executions resolve successfully.

Evidence

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

Human Verification (required)

  • Verified scenarios: local OpenClaw runtime harness with a real config-path plugin, RED/GREEN regression, related plugin registry tests, formatting, staged secret scan, changed gate.
  • Edge cases checked: compatible active registry reuse, pinned channel registry behavior, active runtime registry filtering.
  • What you did not verify: private reporter plugin, live sub-agent archival timing, remote Crabbox proof due local auth blocker.

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
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: retaining a recovery registry could accidentally replace broader active/channel/http runtime state.
    • Mitigation: retention is descriptor-scoped and stored outside global active state; the regression now verifies unrelated active registry tools survive recovery execution.

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 16, 2026
@clawsweeper

clawsweeper Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 24, 2026, 9:22 AM ET / 13:22 UTC.

Summary
The PR retains a scoped cold-loaded plugin tool registry for cached descriptor-backed tool execution after active registry replacement, and adds focused regression coverage.

PR surface: Source +46, Tests +60. Total +106 across 5 files.

Reproducibility: yes. at source level. Current main and v2026.6.10 still contain the cached descriptor plus forced standalone registry path without retained registry state, and the linked issue plus PR body provide concrete runtime evidence.

Review metrics: 1 noteworthy metric.

  • Registry Lifetime Surface: 1 descriptor-scoped retained registry path added. This matters before merge because cached plugin descriptors would keep runtime registry state after active registry replacement.

Stored data model
Persistent data-model change detected: persistent cache schema: src/plugins/tools.optional.test.ts, persistent cache schema: src/plugins/tools.ts, vector/embedding metadata: src/plugins/runtime/load-context.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #80847
Summary: This PR is the active candidate fix for the canonical cached descriptor plugin-tool registry issue; adjacent registry-state work overlaps but does not replace it.

Members:

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

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

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

Rank-up moves:

  • Get plugin/runtime owner signoff on descriptor-scoped retained registry semantics.
  • Rerun the focused plugin tests and changed gate if the branch is refreshed again.

Risk before merge

  • [P1] Descriptor-scoped retained registries change plugin runtime lifecycle semantics; a plugin/runtime owner should confirm this is the intended compatibility model before merge.
  • [P1] The supplied real proof is strong for the isolated runtime path, but it does not run the reporter's private lossless-claw five-minute sub-agent archival loop end to end.
  • [P1] The PR is mergeable and CI is green, but it should still get normal landing validation against the latest main head before merge.

Maintainer options:

  1. Require runtime owner signoff (recommended)
    Have a plugin/runtime owner confirm that descriptor-scoped retained registries are the intended lifecycle model before merge.
  2. Accept the scoped compatibility risk
    Maintainers can merge with the current proof if they explicitly accept this retained-registry lifetime as the compatibility repair.
  3. Pause for a runtime-handle design
    If retaining registries on descriptors is the wrong abstraction, pause this PR and sponsor a narrower cached-descriptor runtime-handle design.

Next step before merge

  • [P2] The remaining action is maintainer/plugin-runtime owner confirmation of compatibility-sensitive registry lifetime, not an automated repair.

Security
Cleared: The diff is confined to plugin runtime source and tests, with no workflow, dependency, secret, permission, package-resolution, or supply-chain changes found.

Review details

Best possible solution:

Land the descriptor-scoped registry retention fix after plugin/runtime owner signoff and current changed-lane validation, while preserving request-local tool-discovery behavior.

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

Yes, at source level. Current main and v2026.6.10 still contain the cached descriptor plus forced standalone registry path without retained registry state, and the linked issue plus PR body provide concrete runtime evidence.

Is this the best way to solve the issue?

Yes, conditionally. Descriptor-scoped retention is the narrowest fix I found for the cached-descriptor path, while globally installing the recovery registry would conflict with request-local tool-discovery behavior.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: The PR targets a confirmed plugin tool registry lifecycle regression with limited plugin-runtime blast radius.
  • merge-risk: 🚨 compatibility: The diff changes how descriptor-backed plugin tools retain runtime registry state across registry replacement, which can affect existing plugin lifecycles.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes copied terminal output from a local OpenClaw runtime harness showing cached descriptor execution succeeds twice after active registry replacement while unrelated active registry state survives.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied terminal output from a local OpenClaw runtime harness showing cached descriptor execution succeeds twice after active registry replacement while unrelated active registry state survives.
Evidence reviewed

PR surface:

Source +46, Tests +60. Total +106 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 3 67 21 +46
Tests 2 60 0 +60
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 127 21 +106

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts --testNamePattern 'retains cold-loaded plugin tools'.
  • [P1] node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/runtime/load-context.test.ts src/plugins/runtime/standalone-runtime-registry-loader.test.ts.
  • [P1] pnpm check:changed --base origin/main.

What I checked:

  • Root and scoped policy read: Root AGENTS.md and src/plugins/AGENTS.md were read fully; plugin runtime registry and cache behavior are compatibility-sensitive under the repo policy. (src/plugins/AGENTS.md:29, 7844b0844568)
  • Current main lacks retained cached descriptor registry: Cached descriptor execution on current main builds a tool-discovery load and resolves a registry without passing or storing retained registry state. (src/plugins/tools.ts:692, 7844b0844568)
  • Current main forced cold load is one-shot: When an active/channel registry exists but lacks scoped plugin tools, current main forces a standalone load with installRegistry disabled and returns it without a descriptor-scoped handle. (src/plugins/tools.ts:927, 7844b0844568)
  • Tool-discovery global install is intentionally avoided: Current main documents that tool-discovery registries should remain request-local rather than replacing active provider/channel/http-route registries. (src/plugins/runtime/standalone-runtime-registry-loader.ts:96, 7844b0844568)
  • PR head adds descriptor-scoped retention: The PR head adds a WeakMap cleared with the descriptor cache, passes retainedRegistry/onRetainRegistry through cached execution, and prefers the retained scoped registry before cold-loading again. (src/plugins/tools.ts:41, 99ce23e54179)
  • PR regression test covers replacement and repeat execution: The new test resolves cached descriptors, replaces active registry with an unrelated live registry that still declares the plugin id, executes the cached descriptor twice, and verifies unrelated active state survives. (src/plugins/tools.optional.test.ts:2150, 99ce23e54179)

Likely related people:

  • lilesjtu: Commit 66ffb29 added the adjacent partial-registry cold-load behavior with forced cold-load semantics that current main carries into this retained-registry gap. (role: recent registry fallback contributor; confidence: high; commits: 66ffb29679c7; files: src/plugins/tools.ts, src/plugins/tools.optional.test.ts)
  • medns: PR 93276 changed adjacent tool-discovery request-local registry behavior in the same runtime surface and is important context for why global registry replacement is risky. (role: recent area contributor; confidence: medium; commits: 0781dae6204e; files: src/plugins/runtime/standalone-runtime-registry-loader.ts, src/plugins/tools.ts, src/gateway/server-methods/tools-catalog.test.ts)
  • zanni098: Commit 3adbbe7 fixed cached descriptor runtime-name dispatch in the same createCachedDescriptorPluginTool execution path. (role: cached descriptor contributor; confidence: medium; commits: 3adbbe7c34b5; files: src/plugins/tools.ts, src/plugins/tools.optional.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.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 16, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@luoyanglang

luoyanglang commented May 16, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the ClawSweeper P2 in 865ba9b. The forced cold-loaded recovery registry is no longer installed into global active state; cached descriptor execution now retains it in descriptor-scoped state and reuses that scoped registry only for the cached descriptor path.

Added regression coverage to the existing cached lifecycle test so an unrelated active registry tool remains in the active registry after both cached descriptor executions.

Local verification after the fix:

  • RED before fix: targeted regression failed because active registry was replaced and the unrelated-live entry disappeared.
  • GREEN: OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts --testNamePattern 'retains cold-loaded plugin tools'
  • Related suite: OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/active-runtime-registry.test.ts src/plugins/runtime.channel-pin.test.ts
  • pnpm exec oxfmt --check --threads=1 src/plugins/tools.ts src/plugins/tools.optional.test.ts src/plugins/runtime/standalone-runtime-registry-loader.ts CHANGELOG.md
  • git diff --check
  • pnpm check:changed
  • gitleaks protect --staged --redact

Updated the PR body with new live terminal output showing cached descriptor execution succeeds while the unrelated active registry owner remains unrelated-live after both executions.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. P2 Normal backlog priority with limited blast radius. labels May 16, 2026
@luoyanglang
luoyanglang force-pushed the wolf/plugin-tool-registry-retention branch from 865ba9b to 3557b86 Compare May 17, 2026 10:20
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 17, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. labels May 17, 2026
@luoyanglang
luoyanglang force-pushed the wolf/plugin-tool-registry-retention branch from 3557b86 to d71aaaf Compare May 17, 2026 10:45
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 17, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 17, 2026
@luoyanglang

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Requesting a fresh review to refresh stale rating/status labels. Current durable review says needs maintainer review before merge, proof is sufficient, and there is no repair lane, but the PR labels only show proof/P2/impact without rating/status.

@clawsweeper

clawsweeper Bot commented May 22, 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.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. labels May 22, 2026
@clawsweeper

clawsweeper Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Tiny Review Wisp

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: sleeps inside passing CI.
Image traits: location green-check meadow; accessory green check lantern; palette charcoal, cyan, and signal green; mood sleepy but ready; pose guarding a tiny green check; shell matte ceramic shell; lighting calm overcast light; background delicate sparkle particles.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Tiny Review Wisp 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.

@luoyanglang
luoyanglang force-pushed the wolf/plugin-tool-registry-retention branch from d71aaaf to 26fe283 Compare May 22, 2026 16:43
@luoyanglang

Copy link
Copy Markdown
Contributor Author

Rebased this PR onto current origin/main and addressed the ClawSweeper installRecords finding in head 26fe283.\n\nMaintenance summary:\n- Preserved current-main PluginRuntimeLoadContext.installRecords propagation.\n- Kept buildPluginRuntimeLoadOptionsFromValues passing installRecords through to PluginLoadOptions.\n- Kept current main's ownerOnly removal; no ownerOnly plumbing is restored.\n- Kept the PR's final metadata snapshot behavior so manifestRegistry and installRecords now come from the final snapshot after auto-enable/config resolution.\n\nLocal validation:\n- OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts --testNamePattern 'retains cold-loaded plugin tools' -> 1 passed\n- OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=120000 node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/active-runtime-registry.test.ts src/plugins/runtime.channel-pin.test.ts -> 3 files passed, 78 tests passed\n- pnpm check:changed --base origin/main -> passed\n- git diff --check origin/main..HEAD -> passed\n- gitleaks protect --staged --redact -> no leaks found\n\nNote: crabbox-wrapper could not run from this executor because the local crabbox AWS provider has no available credentials/IMDS role, so I used local pnpm check:changed against origin/main for the changed-lane validation.\n\n@clawsweeper re-review

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 22, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels May 22, 2026
@luoyanglang
luoyanglang force-pushed the wolf/plugin-tool-registry-retention branch from a5d760f to cc44983 Compare May 26, 2026 19:05
@luoyanglang

Copy link
Copy Markdown
Contributor Author

Rebased onto current origin/main (b56ddcc6ff) to refresh the stale CI state after the previous security-fast job was cancelled. I could not rerun that GitHub Actions job directly because rerun requires repository admin rights, so this is a contributor-side rebase-only refresh; patch scope is unchanged.

Local verification on the rebased head cc44983046:

timeout 300s node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/runtime/load-context.test.ts --reporter=dot --testTimeout=30000
# Test Files 2 passed; Tests 66 passed

git diff --check origin/main..HEAD
# passed

node scripts/check-no-conflict-markers.mjs
# passed

gitleaks detect --redact --log-opts origin/main..HEAD
# no leaks found

Note: node scripts/check-changed.mjs --base origin/main started but blocked locally while pnpm tried to re-fetch optional platform packages from the npm registry (@zed-industries/codex-acp-*, @openai/codex-*, @anthropic-ai/claude-agent-sdk-*) and kept retrying. I stopped that local run and used the targeted plugin tests plus repository guard checks above for this rebase-only CI refresh.

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 26, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 26, 2026
@luoyanglang

Copy link
Copy Markdown
Contributor Author

Addressed the ClawSweeper P3 changelog finding in head 8c5b4be3e7.

Change:

  • Removed only the two release-owned CHANGELOG.md entries flagged by ClawSweeper.
  • No source, runtime, or test behavior changes.

Local verification:

git diff --check
# passed

node scripts/check-no-conflict-markers.mjs
# passed

gitleaks protect --staged --redact
# no leaks found

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 27, 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.

Re-review progress:

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 27, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels May 27, 2026
@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

@luoyanglang
luoyanglang force-pushed the wolf/plugin-tool-registry-retention branch from 8c5b4be to a971bc5 Compare May 29, 2026 07:57
@luoyanglang

Copy link
Copy Markdown
Contributor Author

Rebased onto current origin/main (854cb9292d) to satisfy the new required Dependency Guard baseline.

New head: a971bc5280fe33641ea915c3dcdb1e36240fc1f1. Patch scope is unchanged.

Local validation passed after rebase:

node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/runtime/load-context.test.ts --reporter=dot --testTimeout=30000
# Test Files 2 passed; Tests 66 passed

node scripts/check-changed.mjs --base origin/main
# completed successfully; Dependency Guard lockfile policy passed

git diff --check origin/main..HEAD
git diff --check
node scripts/check-no-conflict-markers.mjs
gitleaks protect --staged --redact
# no issues / no leaks

@clawsweeper re-review

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 29, 2026
@clawsweeper

clawsweeper Bot commented May 29, 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.

Re-review progress:

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 29, 2026
@luoyanglang

Copy link
Copy Markdown
Contributor Author

Refreshed this branch onto current origin/main and resolved the src/plugins/runtime/standalone-runtime-registry-loader.ts conflict. The resolution keeps main's toolDiscovery request-local registry guard and preserves this PR's standalone runtime plugin registry retention path.

Validation run locally:

  • node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/tools.optional.test.ts src/plugins/runtime/load-context.test.ts --reporter=dot --testTimeout=30000 (2 files, 73 tests passed)
  • git diff --check
  • node scripts/check-no-conflict-markers.mjs
  • OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN=false node scripts/check-changed.mjs --base origin/main -- src/plugins/runtime/load-context.test.ts src/plugins/runtime/load-context.ts src/plugins/runtime/standalone-runtime-registry-loader.ts src/plugins/tools.optional.test.ts src/plugins/tools.ts
  • git diff --cached origin/main -- src/plugins/runtime/load-context.test.ts src/plugins/runtime/load-context.ts src/plugins/runtime/standalone-runtime-registry-loader.ts src/plugins/tools.optional.test.ts src/plugins/tools.ts | gitleaks detect --pipe --redact --no-banner (no leaks found)

Note: full staged gitleaks protect --staged --redact was noisy on the merge refresh because staged content included the current-main merge payload; the scoped PR patch scan above is clean.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 20, 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.

@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

Thanks @luoyanglang!

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

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. 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.

bug(plugins): plugin tools intermittently unavailable in sub-agent sessions despite contracts.tools and compiled dist (regression from #56208)

3 participants