Skip to content

[AI-assisted] fix(plugins): scope startup metadata manifest reads#84628

Merged
steipete merged 1 commit into
openclaw:mainfrom
IWhatsskill:fix/plugin-discovery-scope-70533
May 31, 2026
Merged

[AI-assisted] fix(plugins): scope startup metadata manifest reads#84628
steipete merged 1 commit into
openclaw:mainfrom
IWhatsskill:fix/plugin-discovery-scope-70533

Conversation

@IWhatsskill

@IWhatsskill IWhatsskill commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Gateway startup could still rebuild plugin metadata from every installed plugin manifest before narrowing to the configured startup set.
  • Solution: carry a conservative startup plugin-id scope into metadata snapshot loading when the Installed Plugin Index can prove the narrowed set safely.
  • What changed: metadata snapshots can carry scoped pluginIds; lookup/startup paths pass a conservative pluginIdScope; startup scoping carries indexed activation.onConfigPaths owners such as browser; persisted installed indexes preserve that startup.configPaths metadata; scoped current snapshots require an exact caller-requested scope before reuse; unscoped Gateway config-validation snapshots are not reused for restrictive startup bootstrap.
  • What did NOT change (scope boundary): no plugin config shape changes, no provider/channel activation semantics changes, no compat bundled-discovery shortcut.

Motivation

#70533 is a startup stability problem: a restrictive plugin setup should not crash-loop or pay full manifest reconstruction cost just because unrelated installed plugins exist. This keeps the startup path on the Installed Plugin Index when it can safely prove the manifest subset, and falls back to the old unscoped behavior when it cannot.

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: restrictive gateway startup plugin scope still caused full installed-index manifest reconstruction before startup narrowing.
  • Real environment tested: isolated Linux testserver disposable repo, Node v22.22.2, pnpm 11.1.2, origin/main at a13468320c compared with this patch.
  • Exact steps or command run after this patch: ran TSX diagnostic scripts through the real loadPluginLookUpTable -> loadPluginMetadataSnapshot -> loadPluginManifestRegistryForInstalledIndex -> resolveGatewayStartupPluginPlanFromRegistry path using valid 96-plugin Installed Plugin Index fixtures.
  • Evidence after fix:
{
  "label": "after-rebased-patch-confirm",
  "indexPluginCount": 96,
  "manifestPluginCount": 1,
  "startupPluginIds": ["openai"],
  "loadedPluginIds": ["openai"],
  "diagnosticCount": 0
}
  • Observed result after fix: the Installed Plugin Index still contains 96 plugins, but metadata manifest reconstruction reads only the one allowed startup plugin manifest; startup selection remains ["openai"].
  • Additional blocker-fix proof:
{
  "config": {
    "browser": { "enabled": true },
    "channels": {},
    "plugins": {
      "allow": ["openai"],
      "slots": { "memory": "none" }
    }
  },
  "results": [
    {
      "label": "indexed-config-path-scope",
      "indexPluginCount": 96,
      "manifestPluginCount": 2,
      "startupPluginIds": ["openai", "browser"],
      "loadedPluginIds": ["browser", "openai"],
      "diagnosticCount": 0
    },
    {
      "label": "persisted-index-config-path-roundtrip",
      "indexPluginCount": 96,
      "manifestPluginCount": 2,
      "startupPluginIds": ["openai", "browser"],
      "loadedPluginIds": ["browser", "openai"],
      "persistedBrowserConfigPaths": ["browser"],
      "diagnosticCount": 0
    },
    {
      "label": "legacy-index-safe-fallback",
      "indexPluginCount": 96,
      "manifestPluginCount": 96,
      "startupPluginIds": ["openai", "browser"],
      "diagnosticCount": 0
    }
  ]
}
  • Observed blocker-fix result: browser.enabled=true is preserved under a restrictive plugins.allow=["openai"]; new and persisted indexes keep startup.configPaths=["browser"] and stay scoped to 2 manifests, while legacy indexes without indexed config-path metadata fall back unscoped instead of losing browser.
  • Full Gateway startup path proof:
{
  "path": [
    "readConfigFileSnapshotWithPluginMetadata",
    "loadGatewayStartupConfigSnapshot",
    "prepareGatewayPluginBootstrap"
  ],
  "validationSnapshot": {
    "pluginIds": "unscoped",
    "manifestPluginCount": 96
  },
  "bootstrapManifestLoads": [["browser"], ["browser"], ["browser", "openai"]],
  "bootstrapLookup": {
    "pluginIds": ["browser", "openai"],
    "manifestPluginCount": 2
  },
  "startupPluginIds": ["openai", "browser"]
}
  • Observed full-path result: the real config-validation snapshot is still unscoped with 96 manifests, but startup bootstrap does not reuse it for the restrictive allowlist. The final bootstrap lookup reloads the scoped ["browser","openai"] manifests and starts the expected plugins.
  • What was not tested: no production credentials, no persistent services, no real external provider/channel account.
  • Before evidence:
{
  "label": "before-rebased-origin-main",
  "indexPluginCount": 96,
  "manifestPluginCount": 96,
  "startupPluginIds": ["openai"],
  "diagnosticCount": 0
}

Root Cause (if applicable)

  • Root cause: metadata snapshot loading had no way to receive a conservative startup plugin-id scope after the Installed Plugin Index was available, so it reconstructed the installed manifest registry for the full index before startup planning narrowed plugin ids.
  • Missing detection / guardrail: tests covered startup narrowing and metadata memoization separately, but not the manifest reconstruction count for restrictive gateway startup allowlists.
  • Contributing context (if known): some startup intent, config-path activation, channel, provider, slot, and harness decisions can only be trusted when the Installed Plugin Index can map them without reading manifests; unsafe cases need to stay unscoped.

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/commands/status.summary.redaction.test.ts
    • src/gateway/pr84628-startup-snapshot-proof.temp.test.ts (temporary proof test, not committed)
    • src/plugins/plugin-lookup-table.test.ts
    • src/plugins/installed-plugin-index-store.test.ts
    • src/plugins/channel-plugin-ids.test.ts
    • src/plugins/plugin-metadata-snapshot.memo.test.ts
    • src/plugins/current-plugin-metadata-snapshot.test.ts
  • Scenario the test should lock in: restrictive plugins.allow startup config passes a narrow scope to installed-index manifest reconstruction; config-path activation owners such as browser stay included; conservative fallback remains unscoped for compat discovery, legacy indexes, or unmappable providers.
  • Why this is the smallest reliable guardrail: it asserts the actual manifest-registry load boundary without needing external plugin credentials.
  • Existing test that already covers this (if any): none before this PR.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

Gateway startup with a restrictive plugin allowlist can avoid reading unrelated installed plugin manifests when the startup scope is safe to prove from the Installed Plugin Index. Unsafe configs keep existing unscoped behavior.

Diagram (if applicable)

Before:
Installed Index (96 plugins) -> read 96 manifests -> startup plan -> openai

After:
Installed Index (96 plugins) -> conservative scope ["browser","openai"] when browser config is present -> read 2 manifests -> startup plan -> openai + browser

Security Impact (required)

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

Repro + Verification

Environment

  • OS: Linux testserver disposable run
  • Runtime/container: Node v22.22.2, pnpm 11.1.2
  • Model/provider: N/A
  • Integration/channel (if any): synthetic installed plugin fixture; no external channel account
  • Relevant config (redacted): plugins.allow=["openai"], plugins.slots.memory="none"; blocker regression also uses browser.enabled=true

Steps

  1. On origin/main, run the diagnostic fixture through loadPluginLookUpTable.
  2. Apply this patch.
  3. Run the same diagnostic fixture again.
  4. Run focused regression tests, format, typecheck, and targeted lint.

Expected

  • Startup still selects openai.
  • browser.enabled=true still selects browser even when plugins.allow only lists openai.
  • Manifest reconstruction only reads the scoped startup plugin(s) after the patch.
  • Conservative fallback paths remain unscoped when the Installed Plugin Index cannot prove the mapping.

Actual

  • Before: manifestPluginCount=96, startupPluginIds=["openai"].
  • After: manifestPluginCount=1, loadedPluginIds=["openai"], startupPluginIds=["openai"].
  • After blocker repair: manifestPluginCount=2, loadedPluginIds=["browser","openai"], startupPluginIds=["openai","browser"] for browser.enabled=true.
  • After persisted-index repair: persisted read/write roundtrip keeps persistedBrowserConfigPaths=["browser"], manifestPluginCount=2, and diagnosticCount=0.
  • After Gateway startup snapshot repair: config-validation snapshot remains pluginIds="unscoped" with manifestPluginCount=96, but bootstrap reloads scoped ["browser","openai"] and lookup ends at manifestPluginCount=2.

Evidence

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

Validation:

node scripts/run-vitest.mjs src/commands/status.summary.redaction.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/manifest-registry-installed.test.ts src/plugins/channel-plugin-ids.test.ts src/gateway/server-startup-plugins.test.ts src/gateway/server-plugins.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/manifest-contract-eligibility.test.ts src/plugins/tools.optional.test.ts
10 files / 269 tests passed

corepack pnpm exec oxfmt --check --threads=1 src/plugins/plugin-metadata-snapshot.ts src/plugins/plugin-metadata-snapshot.types.ts src/plugins/plugin-lookup-table.ts src/plugins/manifest-registry-installed.ts src/plugins/effective-plugin-ids.ts src/plugins/gateway-startup-plugin-ids.ts src/gateway/server-startup-plugins.ts src/gateway/server-plugins.ts src/commands/status.summary.redaction.test.ts
passed

git diff --check
passed

node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
passed

node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json <11 changed files>
0 warnings / 0 errors

ClawSweeper follow-up acceptance after persisted-index schema repair:

node scripts/run-vitest.mjs src/plugins/installed-plugin-index-store.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts
4 files / 150 tests passed

git diff --check
passed

node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
passed

node_modules/.bin/oxfmt --check --threads=1 src/plugins/installed-plugin-index-store.ts src/plugins/installed-plugin-index-store.test.ts
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/plugins/installed-plugin-index-store.ts src/plugins/installed-plugin-index-store.test.ts
0 warnings / 0 errors

ClawSweeper follow-up after Gateway startup snapshot reuse repair:

node scripts/run-vitest.mjs src/gateway/pr84628-startup-snapshot-proof.temp.test.ts --reporter=verbose
3 Vitest projects / 3 tests passed

node scripts/run-vitest.mjs src/plugins/installed-plugin-index-store.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts
4 files / 151 tests passed

git diff --check
passed

node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
passed

node_modules/.bin/oxfmt --check --threads=1 src/plugins/gateway-startup-plugin-ids.ts src/plugins/channel-plugin-ids.ts src/plugins/plugin-lookup-table.ts src/plugins/plugin-lookup-table.test.ts
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/plugins/gateway-startup-plugin-ids.ts src/plugins/channel-plugin-ids.ts src/plugins/plugin-lookup-table.ts src/plugins/plugin-lookup-table.test.ts
0 warnings / 0 errors

ClawSweeper follow-up after current-snapshot exact-scope repair:

Commit:
05abd2ca1f fix(plugins): require exact current snapshot scope

Changed:
src/plugins/current-plugin-metadata-snapshot.ts
src/plugins/current-plugin-metadata-snapshot.test.ts

Behavior locked in:
getCurrentPluginMetadataSnapshot() only reuses a current snapshot for a scoped pluginIds request when the current snapshot has the exact same normalized pluginIds scope. Unscoped current snapshots are rejected for scoped requests.

node scripts/run-vitest.mjs src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/installed-plugin-index-store.test.ts
5 files / 166 tests passed

git diff --check
passed

node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
passed

node_modules/.bin/oxfmt --check --threads=1 src/plugins/current-plugin-metadata-snapshot.ts src/plugins/current-plugin-metadata-snapshot.test.ts
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/plugins/current-plugin-metadata-snapshot.ts src/plugins/current-plugin-metadata-snapshot.test.ts
0 warnings / 0 errors

ClawSweeper follow-up after scoped current-snapshot exact-scope repair:

Commit:
216ef4677e fix(plugins): require exact scoped current snapshots

Changed:
src/plugins/current-plugin-metadata-snapshot.ts
src/plugins/current-plugin-metadata-snapshot.test.ts

Behavior locked in:
Scoped current snapshots are reused only when the caller asks for the exact same normalized pluginIds scope. Scoped snapshots are rejected for unscoped/config-only requests, including allowScopedSnapshot=true without pluginIds.

node scripts/run-vitest.mjs src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/installed-plugin-index-store.test.ts
5 files / 166 tests passed

git diff --check
passed

node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
passed

node_modules/.bin/oxfmt --check --threads=1 src/plugins/current-plugin-metadata-snapshot.ts src/plugins/current-plugin-metadata-snapshot.test.ts
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/plugins/current-plugin-metadata-snapshot.ts src/plugins/current-plugin-metadata-snapshot.test.ts
0 warnings / 0 errors

pnpm check:changed
attempted; conflict/changelog/dependency guards plus core and core-test TypeScript passed, then full core lint was killed by `tsgolint` SIGKILL on the testserver. Targeted Oxlint for the changed repair files passed with 0 warnings / 0 errors.

Additional note: origin/main @ a13468320c failed test/tsconfig/tsconfig.core.test.json before this patch because status.summary.redaction.test.ts had not been updated for the newer SessionStatus fields. This PR includes that test-only fixture update so check:changed can pass cleanly on the rebased branch.

Human Verification (required)

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

  • Verified scenarios: before/after runtime manifest reconstruction count on the real OpenClaw metadata lookup path; full Gateway config-snapshot to plugin-bootstrap path; restrictive allowlist scope; config-path activation owner retention; legacy index safe fallback; compat discovery fallback; unmappable provider fallback; scoped/unscoped memo separation; configless scoped snapshot reuse rejection; scoped current snapshot exact-scope reuse only.
  • Edge cases checked: disabled plugin entries are removed from the scope, direct configured channels/providers only scope when the Installed Plugin Index can map them, scope ids outside the index and legacy config-path activation metadata fall back to unscoped loading.
  • What I did not verify: real production provider/channel credentials or long-running gateway service startup.

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

Risks and Mitigations

  • Risk: overly aggressive startup scoping could hide a plugin whose startup intent is only manifest-visible.
    • Mitigation: scope is only used when allowlists/config entries/config-path activation/slots/direct channel/provider/harness ids can be mapped from the Installed Plugin Index; ambiguous compat, provider, channel, legacy-index, or out-of-index cases return to unscoped manifest reconstruction.

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: L proof: supplied External PR includes structured after-fix real behavior proof. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 25, 2026, 4:54 AM ET / 08:54 UTC.

Summary
The PR scopes Gateway startup/config-validation plugin metadata snapshots, adds installed-index ownership metadata for startup scoping, and expands plugin/Gateway regression coverage for scoped and fallback paths.

PR surface: Source +1001, Tests +1063. Total +2064 across 23 files.

Reproducibility: yes. Source inspection shows current main has no scoped metadata-snapshot startup path, and the PR body gives a concrete before/after diagnostic path through loadPluginLookUpTable and metadata snapshot loading.

Review metrics: 2 noteworthy metrics.

  • Changed files: 23 files affected. The PR spans plugin metadata snapshots, Gateway startup planning, config validation, installed-index persistence, and focused tests, so reviewers need to cover the whole startup decision path.
  • Persisted index metadata: 2 optional fields added. Adding startup config-path and contribution metadata changes upgrade/fallback behavior for users with existing persisted plugin indexes.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

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

Rank-up moves:

  • Refresh the real behavior proof against e901898.
  • Get plugin/Gateway owner review on scoped owner inference and legacy persisted-index fallback behavior.

Proof guidance:
Needs stronger real behavior proof before merge: The PR body has strong live-output proof for an earlier branch state, but the latest refactor commit came after that proof was invalidated; update the PR body with current-head proof, redacting private data, to trigger a fresh review or ask for @clawsweeper re-review.

Risk before merge

  • Compatibility remains the main merge risk: if the installed-index scope lookup misses a provider, channel, harness, config-path, model, or startup owner, restrictive allowlist users could omit a plugin that the old unscoped path would have loaded.
  • The latest head changed the central owner-map implementation after the supplied proof was marked stale, so maintainers should require refreshed current-head proof before merge.

Maintainer options:

  1. Refresh proof, then owner-review scoping (recommended)
    Ask for proof against e901898 and have a plugin/Gateway owner review the index-derived owner maps and fallback behavior before merge.
  2. Accept the scoped-startup risk
    Maintainers can intentionally accept the compatibility risk if they decide the supplied tests and stale-but-detailed diagnostics are enough for this performance fix.
  3. Pause for a narrower fix
    If owner inference remains too broad, pause this PR and keep Plugin discovery loads all dist/extensions/ manifests at boot regardless of tools.allow (~500 MB structural heap) #70533 as the canonical issue for a smaller startup-scoping repair.

Next step before merge
The remaining action is current-head proof plus maintainer/owner compatibility review, not a narrow automated repair.

Security
Cleared: No concrete security or supply-chain regression was found; the diff does not add dependencies, CI workflows, new permissions, network calls, or secrets handling.

Review details

Best possible solution:

Land the scoped startup metadata approach only after refreshed proof against the latest head and plugin/Gateway owner review confirm that every uncertain owner falls back to unscoped discovery.

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

Yes. Source inspection shows current main has no scoped metadata-snapshot startup path, and the PR body gives a concrete before/after diagnostic path through loadPluginLookUpTable and metadata snapshot loading.

Is this the best way to solve the issue?

Likely yes, but not merge-ready without refreshed proof and owner review. Carrying a conservative plugin-id scope from the installed index is maintainable if every uncertain ownership case falls back to unscoped discovery.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body has strong live-output proof for an earlier branch state, but the latest refactor commit came after that proof was invalidated; update the PR body with current-head proof, redacting private data, to trigger a fresh review or ask for @clawsweeper re-review.
  • remove status: ⏳ waiting on author: Current PR status label is status: 📣 needs proof.

Label justifications:

  • P1: The linked issue describes a real Gateway startup stability/performance problem that can contribute to high memory floor or crash-loop behavior in restrictive plugin setups.
  • merge-risk: 🚨 compatibility: The PR changes startup manifest loading from unscoped discovery to index-derived scoped discovery when the branch believes the scope is provable.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body has strong live-output proof for an earlier branch state, but the latest refactor commit came after that proof was invalidated; update the PR body with current-head proof, redacting private data, to trigger a fresh review or ask for @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +1001, Tests +1063. Total +2064 across 23 files.

View PR surface stats
Area Files Added Removed Net
Source 15 1009 8 +1001
Tests 8 1065 2 +1063
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 23 2074 10 +2064

Acceptance criteria:

  • node scripts/run-vitest.mjs src/commands/status.summary.redaction.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/manifest-registry-installed.test.ts src/plugins/channel-plugin-ids.test.ts src/gateway/server-startup-plugins.test.ts src/gateway/server-plugins.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/manifest-contract-eligibility.test.ts src/plugins/tools.optional.test.ts
  • node scripts/run-vitest.mjs src/plugins/installed-plugin-index-store.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts
  • git diff --check
  • node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo

What I checked:

  • Repository policy applied: Root and scoped plugin/Gateway AGENTS.md files were read; they treat plugin metadata, startup checks, fallback behavior, persisted metadata, and plugin routing as compatibility-sensitive surfaces. (AGENTS.md:1, c791e4242bc8)
  • Current main lacks the scoped metadata API: A current-main search found no createGatewayStartupMetadataPluginIdScope, resolveGatewayStartupMetadataPluginIds, pluginIdScope, or installed-plugin-index-scope-lookup implementation under the plugin/config/Gateway paths, so the central change is not already implemented on main. (c791e4242bc8)
  • PR scoped startup path: At the PR head, loadPluginLookUpTable builds a Gateway startup metadata plugin-id scope, rejects incompatible provided snapshots, and passes the scope into resolvePluginMetadataSnapshot. (src/plugins/plugin-lookup-table.ts:52, e9018988997e)
  • PR installed-index scope lookup: The latest head moves owner-map logic into createInstalledPluginIndexScopeLookup, including direct channel/provider owners, contribution owners, shorthand model support, installed-plugin-id checks, and config-path metadata completeness. (src/plugins/installed-plugin-index-scope-lookup.ts:198, e9018988997e)
  • Related issue remains the canonical bug: The PR body uses closing syntax for Plugin discovery loads all dist/extensions/ manifests at boot regardless of tools.allow (~500 MB structural heap) #70533, which reports full bundled-plugin manifest reads at boot despite restrictive plugin allowlists and remains open in the provided GitHub context.
  • Proof needs refresh for latest head: The supplied PR body contains detailed live diagnostic output, but the timeline shows the proof-sufficient label was removed after the latest e901898 refactor commit, so current-head proof is not yet sufficient. (e9018988997e)

Likely related people:

  • steipete: Authored the merged plugin metadata snapshot reuse PR on main and the latest PR commits that refactor validation/startup scoping and installed-index lookup behavior. (role: recent area contributor and likely follow-up owner; confidence: high; commits: 431467405486, d4299dcbaa53, d047ab5462e4; files: src/plugins/plugin-metadata-snapshot.ts, src/plugins/plugin-lookup-table.ts, src/plugins/gateway-startup-plugin-ids.ts)
  • IWhatsskill: Authored the initial scoped startup metadata commits and persisted-index repair in this PR, so they have direct context for the proposed branch even though current-main ownership should route through plugin/Gateway reviewers. (role: branch contributor with domain context; confidence: medium; commits: e7fd3f849511, d602378fdf27, ecc8f565ad9a; files: src/plugins/plugin-lookup-table.ts, src/plugins/plugin-metadata-snapshot.ts, src/plugins/gateway-startup-plugin-ids.ts)
  • obviyus: The provided ClawSweeper assist notes obviyus was pulled into this compatibility-sensitive plugin/Gateway startup discussion, making them a plausible reviewer even without direct local commit evidence in this checkout. (role: reviewer candidate from discussion; confidence: low; files: src/plugins/gateway-startup-plugin-ids.ts, src/plugins/plugin-lookup-table.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.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@IWhatsskill IWhatsskill force-pushed the fix/plugin-discovery-scope-70533 branch from abf0aeb to 6693cdc Compare May 20, 2026 17:56
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 20, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 20, 2026
@IWhatsskill

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@IWhatsskill IWhatsskill force-pushed the fix/plugin-discovery-scope-70533 branch from 6693cdc to d464cb2 Compare May 20, 2026 18:23
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 20, 2026
@IWhatsskill

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. 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. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 20, 2026
@IWhatsskill IWhatsskill marked this pull request as ready for review May 20, 2026 18:53
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. 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 May 20, 2026
@clawsweeper clawsweeper Bot added the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label May 20, 2026
@IWhatsskill

Copy link
Copy Markdown
Contributor Author

@clawsweeper hatch

@clawsweeper

clawsweeper Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper PR egg hatch requested.

I queued a comment sync for this PR. If the egg is hatchable, ClawSweeper will generate the image once and update the existing review comment.
Action: PR egg hatch queued (workflow sweep.yml, event repository_dispatch).
The ASCII egg stays as the fallback.

@Takhoffman

Copy link
Copy Markdown
Contributor

@clawsweeper ask history of this problem, risks and who should review it

@clawsweeper

clawsweeper Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper assist is taking a look at your question.

I queued a lightweight read-only assist pass. It will post a separate answer comment and will not edit the durable ClawSweeper review comment or trigger close, merge, repair, label, or branch changes.

Request: history of this problem, risks and who should review it

@clawsweeper

clawsweeper Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper assist: This PR is the proposed fix for #70533, where restrictive plugin configs still paid full startup manifest discovery cost. The history is: issue #70533 reported ~104 bundled manifests being read/validated at boot despite a small allowlist; this PR narrowed startup metadata reads, then went through several follow-up commits/re-reviews to handle snapshot reuse, bootstrap rescoping, and legacy persisted indexes. Main risk is compatibility: if the new pre-manifest scope misses a startup owner, a plugin that used to load under the unscoped path could be omitted.

Evidence:

  • Linked issue: Plugin discovery loads all dist/extensions/ manifests at boot regardless of tools.allow (~500 MB structural heap) #70533 reported structural startup heap from reading all bundled plugin manifests despite allowlist config.
  • PR proof says before patch manifestPluginCount=96; after scoped startup path it drops to 1 for openai, or 2 for browser + openai.
  • Follow-up commits include exact-scope snapshot fixes and legacy config-path index refresh: 90d289c44e386fe6d15579a374acd21caa665e7f, 1238192dd1cae0a551250cc77115554c7e207f6b, d38b0c92fd6685ddfc70305c7c8fbab6e436bbcc.
  • ClawSweeper review already flagged the remaining risk as merge-risk: 🚨 compatibility, specifically “a missed pre-manifest startup owner in restrictive allowlist configs.”
  • Validation supplied includes focused plugin/gateway tests, tsgo, formatting, diff check, and oxlint; no production credentials or real external provider/channel account were tested.

Who should review: someone who owns plugin startup/discovery and Gateway bootstrap behavior, plus a maintainer familiar with installed plugin index persistence/migrations. If available, include reviewers previously mentioned on this PR timeline, obviyus and steipete, because they were pulled into the discussion on 2026-05-20.

Suggested next action: Ask a plugin/Gateway maintainer to review the compatibility-sensitive startup scoping, especially config-path activation owners, channels/providers, legacy persisted indexes, and snapshot reuse behavior.


Source: #84628 (comment)
Assist model: gpt-5.5, reasoning low.

@IWhatsskill IWhatsskill force-pushed the fix/plugin-discovery-scope-70533 branch from d38b0c9 to 7d4cbfd Compare May 24, 2026 01:27
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@steipete steipete self-assigned this May 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 25, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. 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. and removed 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 May 25, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 25, 2026
@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 25, 2026
@steipete steipete force-pushed the fix/plugin-discovery-scope-70533 branch from e901898 to 38e10eb Compare May 31, 2026 10:50
steipete added a commit to IWhatsskill/openclaw that referenced this pull request May 31, 2026
Limit plugin metadata snapshots to the channel, provider, and startup surfaces that need them, while preserving unscoped fallback for incomplete index data and provider runtime resolution.

Refs openclaw#84628
Co-authored-by: IWhatsskill <IWhatsskill@users.noreply.github.com>
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label May 31, 2026
Limit plugin metadata snapshots to the channel, provider, and startup surfaces that need them, while preserving unscoped fallback for incomplete index data and provider runtime resolution.

Refs openclaw#84628
Co-authored-by: IWhatsskill <IWhatsskill@users.noreply.github.com>
@steipete steipete force-pushed the fix/plugin-discovery-scope-70533 branch from 38e10eb to 15d43f2 Compare May 31, 2026 10:54
@steipete

Copy link
Copy Markdown
Contributor

Behavior addressed: plugin metadata registry reads for startup/channel/provider paths are scoped to the needed plugin ids, with unscoped fallback when installed-index data is incomplete and provider-runtime reuse only when the scoped snapshot covers the requested provider.

Real environment tested: local macOS checkout on PR head 15d43f2 after rebasing onto current origin/main.

Exact steps or command run after this patch:

  • pnpm test src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/plugin-lookup-table.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/installed-plugin-index-store.test.ts src/plugins/installed-plugin-index.test.ts src/plugins/plugin-registry-snapshot.test.ts src/commands/doctor-plugin-registry.test.ts src/plugins/providers.test.ts
  • node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/agents/embedded-agent-runner/run/attempt.ts src/commands/doctor-plugin-registry.test.ts src/config/io.ts src/plugins/channel-plugin-ids.test.ts src/plugins/channel-plugin-ids.ts src/plugins/current-plugin-metadata-snapshot.test.ts src/plugins/current-plugin-metadata-snapshot.ts src/plugins/gateway-startup-plugin-ids.ts src/plugins/installed-plugin-index-config-path-scope.ts src/plugins/installed-plugin-index-invalidation.ts src/plugins/installed-plugin-index-record-builder.ts src/plugins/installed-plugin-index-scope-lookup.ts src/plugins/installed-plugin-index-store.test.ts src/plugins/installed-plugin-index-store.ts src/plugins/installed-plugin-index-types.ts src/plugins/installed-plugin-index.test.ts src/plugins/installed-plugin-index.ts src/plugins/plugin-lookup-table.test.ts src/plugins/plugin-lookup-table.ts src/plugins/plugin-metadata-snapshot.memo.test.ts src/plugins/plugin-metadata-snapshot.ts src/plugins/plugin-metadata-snapshot.types.ts src/plugins/plugin-registry-snapshot.test.ts src/plugins/plugin-registry-snapshot.ts src/plugins/provider-hook-runtime.ts
  • pnpm tsgo:core
  • pnpm tsgo:core:test
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --prompt "Final rerun after rebasing PR 84628 onto current origin/main. Verify the conflict resolution kept current main image-size import behavior and preserved the scoped plugin metadata/provider-runtime safety fixes."

Evidence after fix: targeted Vitest shards passed 318 tests total; targeted oxlint passed; tsgo core and core-test passed; final autoreview reported no accepted/actionable findings.

Observed result after fix: scoped metadata paths retain provider/channel/startup coverage and fall back safely when the installed index cannot prove a narrowed scope.

What was not tested: full local pnpm check:changed was not run end-to-end in this checkout; the selected changed-lane proof above was run locally and PR CI is running on the pushed head.

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

Labels

agents Agent runtime and tooling commands Command implementations merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin discovery loads all dist/extensions/ manifests at boot regardless of tools.allow (~500 MB structural heap)

3 participants