openclaw - 💡(How to fix) Fix FRD: installed-plugin opt-in for registerTrustedToolPolicy + registerAgentToolResultMiddleware

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

  • Cross-plugin policy composition / merge rules — installed plugins each register their own id; collisions on id should be a load error, not a merge.

Root Cause

An explicit, manifest-declared opt-in for both surfaces, available to installed plugins. Two equivalent shapes — either works, but manifest-field is preferred because it keeps the trust posture declarative and reviewable at install time:

Code Example

{
  "id": "bytedesk-workflow-harness",
  "contracts": {
    "tools": ["bytedesk_workflow_*"],
    "trustedToolPolicies": ["bytedesk-workflow"],
    "agentToolResultMiddleware": ["bytedesk-workflow"]
  }
}

---

{
  plugins: {
    entries: {
      "bytedesk-workflow-harness": {
        enabled: true,
        trustedToolPolicy: true,
        agentToolResultMiddleware: true,
      },
    },
  },
}
RAW_BUFFERClick to expand / collapse

[FRD] Installed-plugin opt-in for registerTrustedToolPolicy + registerAgentToolResultMiddleware

Status: Draft (ByteDesk-internal). Ready to file at openclaw/openclaw issues. Author: ByteDesk Platform team (companion to BDP-1207, follow-up from BDP-1198 in bytedesk-platform). Reference: docs/plugins/hooks.md, docs/plugins/building-plugins.md, docs/plugins/manifest.md.

Problem

The OpenClaw plugin SDK currently restricts two host-trusted registration surfaces to bundled plugins only. When an installed plugin (e.g. one loaded via plugins.load.paths or openclaw plugins install) calls them, the gateway emits warnings and skips registration:

  • api.registerTrustedToolPolicy(...)only bundled plugins can register trusted tool policies
  • api.registerAgentToolResultMiddleware(...)only bundled plugins can register agent tool result middleware

This is a reasonable default — these surfaces run with host trust ahead of the standard before_tool_call / after_tool_call hook chain — but it leaves serious gaps for downstream platforms that ship their own first-party plugins outside the OpenClaw image.

ByteDesk hit this on bytedesk-workflow-harness, an installed plugin that implements a workflow control plane on top of OpenClaw primitives. BDP-1198 had to fall back to the public hook chain to keep functionality:

  1. Trusted-policy fallback → before_tool_call hook for the workflow-harness engineering exec-policy / per-cascade budget gate.
  2. Tool-result-middleware fallback → after_tool_call hook for workflow correlation-id tagging and artifact capture.

The fallbacks work, but they have two real costs:

  1. Wrong execution order. before_tool_call hooks for installed plugins run after all bundled-plugin trusted policies. The workflow-harness engineering policy is meant to be the per-cascade budget/exec-policy gate for harness-owned cascades, and ordering matters for deny-decisions.
  2. Reduced surface for middleware. after_tool_call hooks cannot mutate the model-visible tool output the way registerAgentToolResultMiddleware can — only the artifact bag. Workflow-correlation tagging into model-visible context is therefore not possible from an installed plugin today.

The hard side-step is bundling our plugin into the OpenClaw image, which tightens coupling between OpenClaw releases and the downstream platform release. We'd prefer not to do that just to escape an SDK gate.

Requested upstream primitive

An explicit, manifest-declared opt-in for both surfaces, available to installed plugins. Two equivalent shapes — either works, but manifest-field is preferred because it keeps the trust posture declarative and reviewable at install time:

Option A — manifest field on openclaw.plugin.json (preferred)

Two new optional contract fields, mirroring the existing contracts.tools[] pattern:

{
  "id": "bytedesk-workflow-harness",
  "contracts": {
    "tools": ["bytedesk_workflow_*"],
    "trustedToolPolicies": ["bytedesk-workflow"],
    "agentToolResultMiddleware": ["bytedesk-workflow"]
  }
}

Semantics:

  • Each entry is a policy / middleware id the plugin promises to register at runtime.
  • The gateway records the declaration at plugin discovery (before code load), exactly like contracts.tools[].
  • At api.registerTrustedToolPolicy(id, ...) / api.registerAgentToolResultMiddleware(id, ...) call time, the gateway accepts the registration iff id appears in the matching manifest array.
  • Undeclared policies/middleware continue to log the existing warning and skip registration — the existing bundled-plugin path is unchanged.

This matches the spirit of "if OpenClaw must know it before loading plugin code, put it in openclaw.plugin.json" from manifest.md.

Option B — gateway-config allowlist

Equivalent opt-in via gateway config rather than plugin manifest:

{
  plugins: {
    entries: {
      "bytedesk-workflow-harness": {
        enabled: true,
        trustedToolPolicy: true,
        agentToolResultMiddleware: true,
      },
    },
  },
}

Same runtime gate, decision lives in the operator's config instead of the plugin's manifest. Acceptable as a complement (operator override) but should not be the only opt-in path — manifest declarations are reviewable by openclaw plugins inspect before install.

Either option — ordering guarantee

Document the ordering relationship between installed-plugin trusted policies and bundled-plugin trusted policies. The downstream-useful semantics are:

  • Bundled-plugin trusted policies run first (existing behavior).
  • Installed-plugin trusted policies run next, in plugin-load order.
  • Standard before_tool_call / after_tool_call hooks run last (existing behavior).

This preserves the host-trust default while giving installed plugins a slot that's strictly stronger than the public hook chain.

Out of scope for this FRD

  • Letting installed plugins register registerNodeInvokePolicy host-trusted surfaces — separate trust posture, separate review.
  • Letting installed plugins extend registerSessionExtension defaults — already allowed; just needs the namespace + description fields documented in hooks.md (BDP-1198 path A handled the local-side warning).
  • Cross-plugin policy composition / merge rules — installed plugins each register their own id; collisions on id should be a load error, not a merge.

Docs locations to update upstream

If the primitive lands, the following files in openclaw/openclaw should pick up the opt-in surface in the same change:

FileWhat to add
docs/plugins/manifest.mdNew contracts.trustedToolPolicies[] + contracts.agentToolResultMiddleware[] fields, alongside the existing contracts.tools[] row in the top-level schema table.
docs/plugins/building-plugins.mdA short "Trusted surfaces from installed plugins" section showing the manifest declaration + the api.registerTrustedToolPolicy(...) call, plus the ordering guarantee.
docs/plugins/hooks.mdUpdate the registerTrustedToolPolicy and registerAgentToolResultMiddleware reference rows to note the installed-plugin opt-in and link to the manifest section.
docs/cli/plugins.mdUpdate openclaw plugins inspect --runtime --json output description to surface declared trustedToolPolicies / agentToolResultMiddleware so operators can audit before enabling.

Downstream design we're holding back

ByteDesk's bytedesk-workflow-harness plugin currently ships the hook-based fallback in:

  • bytedesk-openclaw/plugins/bytedesk-workflow-harness/src/harness/trusted-tool-policy.ts
  • bytedesk-openclaw/plugins/bytedesk-workflow-harness/src/harness/tool-result-middleware.ts
  • bytedesk-openclaw/plugins/bytedesk-workflow-harness/src/exec-policy/registry.ts

When the opt-in lands, each will prefer api.registerTrustedToolPolicy(...) / api.registerAgentToolResultMiddleware(...) and fall back to the hook chain only when the gate isn't configured — so we stay forward-compatible with older OpenClaw releases.

Why not just bundle the plugin

Bundling bytedesk-workflow-harness into the OpenClaw image side-steps the restriction but tightens coupling between every OpenClaw release and the workflow-harness release. The harness already targets a published pluginApi / minGatewayVersion range and ships its own lifecycle. The installed-plugin opt-in lets the host trust posture stay explicit without forcing the bundle.

Asked of upstream

  • Confirm whether the bundled-only restriction on these two surfaces is a deliberate long-term trust posture or a default that predates installed-plugin maturity.
  • If extending: pick Option A (manifest) or Option B (gateway config) — or accept both — and scope a single PR that adds the manifest fields, the runtime gate, and the docs updates listed above.
  • If not extending: state that explicitly so downstream platforms can plan around bundling or hook-only fallbacks.

Companion ByteDesk artifacts

  • BDP-1198 — landed Path A (cleared session-extension + nodeInvokePolicy warnings; trusted-policy + middleware fallbacks via hooks).
  • BDP-1207 — this FRD; tracks the upstream ask.
  • docs/workflow-harness.md — the workflow-harness design that motivates the ask (see "Trusted policy" + "Decorator" pattern rows).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING