Skip to content

fix(plugins): load explicit hook plugins at startup#76684

Merged
steipete merged 4 commits into
openclaw:mainfrom
MkDev11:fix/issue-76649-hook-plugins
May 3, 2026
Merged

fix(plugins): load explicit hook plugins at startup#76684
steipete merged 4 commits into
openclaw:mainfrom
MkDev11:fix/issue-76649-hook-plugins

Conversation

@MkDev11

@MkDev11 MkDev11 commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: embedded PI runs reused the Gateway startup plugin scope before reading the global hook runner, but explicitly configured hook plugins could be missing from that scope.
  • Why it matters: external plugins using before_prompt_build or agent_end could work in harness runtimes while remaining invisible to Feishu/main embedded PI runs.
  • What changed: Gateway startup planning now includes explicitly enabled hook-capable plugins, covering manifest hook capability hints and explicit hook policy config.
  • What did NOT change (scope boundary): no Feishu-specific behavior, no hardcoded plugin ids, and no broad loading of unrelated plugins.

Change Type

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

Scope

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

Linked Issue/PR

Root Cause

  • Root cause: startup-scoped runtime registry reuse could omit hook plugins from startup.pluginIds, so embedded PI read a global hook runner without those plugin hooks.
  • Missing detection / guardrail: startup planning did not test hook-capability or explicit hook-policy plugins.
  • Contributing context (if known): v2026.5.2 optimized plugin runtime reuse by scoping runtime loads to startup ids.

Regression Test Plan

  • 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/channel-plugin-ids.test.ts
  • Scenario the test should lock in: explicitly configured non-bundled hook plugins are included in Gateway startup plugin ids.
  • Why this is the smallest reliable guardrail: embedded PI already consumes the startup-scoped runtime registry, so testing startup ids directly catches the omission before runtime hook lookup.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

External hook plugins configured for agent lifecycle hooks are available to embedded PI runs.

Diagram

Before:
embedded PI -> startup-scoped registry without hook plugin -> getGlobalHookRunner() misses hooks

After:
startup planning includes explicit hook plugin -> embedded PI runtime loads it -> hooks are visible

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: local dev checkout
  • Runtime/container: Node/pnpm test environment
  • Model/provider: N/A
  • Integration/channel (if any): embedded PI hook startup planning
  • Relevant config (redacted): explicit plugin hook policy config with allowPromptInjection and allowConversationAccess

Steps

  1. Configure a non-bundled plugin with hook capability or hook policy config.
  2. Resolve Gateway startup plugin ids.
  3. Verify the hook plugin is included in the startup scope.

Expected

  • Hook-capable plugin ids are included in startup runtime scope.

Actual

  • Before this fix, the regression tests returned no hook plugin startup scope.

Evidence

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

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • manifest activation.onCapabilities: ["hook"]
    • explicit plugins.entries.<id>.hooks.allowPromptInjection=true
    • explicit plugins.entries.<id>.hooks.allowConversationAccess=true
  • Edge cases checked:
    • plugin global enable/deny gates still apply
    • startup scope remains targeted
    • no Feishu/plugin-id special casing

Test Plan

  • pnpm exec vitest run --config test/vitest/vitest.plugins.config.ts src/plugins/channel-plugin-ids.test.ts -t "loads explicit hook" -> PASS
  • pnpm test src/agents/runtime-plugins.test.ts src/plugins/loader.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts src/plugins/channel-plugin-ids.test.ts -> PASS
  • pnpm exec oxfmt --check --threads=1 src/plugins/gateway-startup-plugin-ids.ts src/plugins/channel-plugin-ids.test.ts CHANGELOG.md -> PASS
  • pnpm check:changed -> PASS

@clawsweeper

clawsweeper Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR adds hook-aware Gateway startup planning for manifest hook-capability and explicit hook-policy plugins, regression tests, a changelog entry, and a small Codex approval event fire-and-forget cleanup.

Reproducibility: yes. Source inspection shows current main can load embedded PI runtime plugins from snapshot.startup.pluginIds, and the startup planner currently has no hook-capability or explicit hook-policy inclusion path.

Next step before merge
Active implementation PR appears valid; the remaining action is maintainer review and required-check completion, not a repair job.

Security
Cleared: The diff broadens startup loading only for configured hook plugins while preserving plugin gates, with no dependency, workflow, secret, package, or download changes.

Review details

Best possible solution:

Review and land the generic hook-aware startup planner change, preserving plugin enable, deny, and allowlist gates without Feishu-specific behavior or hardcoded plugin IDs.

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

Yes. Source inspection shows current main can load embedded PI runtime plugins from snapshot.startup.pluginIds, and the startup planner currently has no hook-capability or explicit hook-policy inclusion path.

Is this the best way to solve the issue?

Yes. The PR fixes the implicated planner layer generically and adds tests for hook intent plus enable/deny/allowlist gates, which is narrower than a Feishu-specific workaround.

Acceptance criteria:

  • pnpm test src/agents/runtime-plugins.test.ts src/plugins/loader.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts src/plugins/channel-plugin-ids.test.ts
  • pnpm exec oxfmt --check --threads=1 src/plugins/gateway-startup-plugin-ids.ts src/plugins/channel-plugin-ids.test.ts CHANGELOG.md
  • pnpm check:changed

What I checked:

  • Current main scopes runtime loading to startup ids: ensureRuntimePluginsLoaded reads snapshot.startup.pluginIds and passes them as both requiredPluginIds and onlyPluginIds, so any plugin omitted from the startup snapshot is omitted from the runtime registry used by embedded PI. (src/agents/runtime-plugins.ts:39, 103b6d50a5b6)
  • Embedded PI reads hooks after runtime loading: runEmbeddedPiAgent calls ensureRuntimePluginsLoaded(...) before retrieving getGlobalHookRunner(), matching the linked report's failure mode when hook plugins are not loaded into that registry. (src/agents/pi-embedded-runner/run.ts:417, 103b6d50a5b6)
  • Current main has no hook-specific startup branch: The startup planner handles configured channels, harness runtimes, root config activation, speech providers, memory, and context-engine startup cases, but there is no hook capability or hook policy inclusion path before the generic startup filter. (src/plugins/gateway-startup-plugin-ids.ts:448, 103b6d50a5b6)
  • Hook policy is a documented plugin contract: The docs list before_prompt_build and agent_end, and document allowConversationAccess and allowPromptInjection as the relevant plugin hook policy gates. Public docs: docs/plugins/hooks.md. (docs/plugins/hooks.md:241, 103b6d50a5b6)
  • PR patch targets the generic planner and tests the gates: The public PR patch adds canStartExplicitHookPlugin, checks manifest hook capability and explicit hook policy config, and adds regression cases for loading, ambient non-loading, global disablement, denylist, allowlist, and activation-source protection. (src/plugins/gateway-startup-plugin-ids.ts:284, 957f1deb03d4)
  • Linked report remains open and paired: The PR body uses closing syntax for [Bug]: Plugin hooks (before_prompt_build, agent_end) not firing for feishu/main agent in embedded PI runtime (v2026.5.2) #76649, whose report describes the same Feishu embedded PI hook failure; that issue should stay open until this PR is reviewed and merged or closed.

Likely related people:

  • steipete: Recent main history includes plugin startup metadata planning/refactors and this PR's maintainer follow-up commits, plus current-line blame in the startup planner checkout. (role: recent maintainer; confidence: high; commits: fecac7e40aef, 7ac23eeeb581, 39c5bbf08e12; files: src/plugins/gateway-startup-plugin-ids.ts, src/plugins/channel-plugin-ids.test.ts, extensions/codex/src/app-server/approval-bridge.ts)
  • hclsys: Authored the recent context-engine startup-plan fix in the same planner and regression-test surface for an external plugin omitted from gateway startup scope. (role: adjacent startup-scope fix author; confidence: high; commits: deb7b821c195; files: src/plugins/gateway-startup-plugin-ids.ts, src/plugins/channel-plugin-ids.test.ts)
  • DmitryPogodaev: Authored the v2026.5.2 startup runtime registry reuse change identified by the linked issue and touching runtime plugin loading/scoping behavior. (role: related runtime registry reuse author; confidence: medium; commits: 8283c5d6cc3f; files: src/agents/runtime-plugins.ts, src/plugins/runtime/runtime-registry-loader.ts, src/plugins/runtime/standalone-runtime-registry-loader.ts)
  • vincentkoc: Introduced registry-backed gateway startup planning and prior hook registry preservation work that form the broader behavior around this regression. (role: startup planner and hook-runtime history owner; confidence: medium; commits: 674d188153ae, d22279d2e873; files: src/plugins/gateway-startup-plugin-ids.ts, src/agents/runtime-plugins.ts, src/plugins/runtime/standalone-runtime-registry-loader.ts)

Remaining risk / open question:

  • This read-only review did not run the PR's tests or a live Feishu scenario, so required checks should still gate the exact head SHA.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 103b6d50a5b6.

@MkDev11

MkDev11 commented May 3, 2026

Copy link
Copy Markdown
Contributor Author

The branch conflict has been resolved and the PR is now mergeable against main

@steipete steipete force-pushed the fix/issue-76649-hook-plugins branch from 0ad8b11 to 25977de Compare May 3, 2026 14:00
@steipete steipete merged commit d6900ee into openclaw:main May 3, 2026
108 of 109 checks passed
@steipete

steipete commented May 3, 2026

Copy link
Copy Markdown
Contributor

Landed via squash merge onto main.

  • Source head: 957f1de
  • Merge commit: d6900ee
  • Gate: GitHub CI green on 957f1de; local/Testbox checks included targeted plugin tests, approval bridge test, check:changed, and test:changed.

Thanks @MkDev11!

lxe pushed a commit to lxe/openclaw that referenced this pull request May 6, 2026
…(thanks @MkDev11)

Includes explicitly enabled hook-capable plugins in the Gateway startup runtime scope and adds regression coverage for startup hook plugin gating.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…(thanks @MkDev11)

Includes explicitly enabled hook-capable plugins in the Gateway startup runtime scope and adds regression coverage for startup hook plugin gating.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…(thanks @MkDev11)

Includes explicitly enabled hook-capable plugins in the Gateway startup runtime scope and adds regression coverage for startup hook plugin gating.
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…(thanks @MkDev11)

Includes explicitly enabled hook-capable plugins in the Gateway startup runtime scope and adds regression coverage for startup hook plugin gating.
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…(thanks @MkDev11)

Includes explicitly enabled hook-capable plugins in the Gateway startup runtime scope and adds regression coverage for startup hook plugin gating.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Plugin hooks (before_prompt_build, agent_end) not firing for feishu/main agent in embedded PI runtime (v2026.5.2)

2 participants