Skip to content

perf(gateway): propagate config context in model normalization to avoid stale policy warning#86372

Closed
medns wants to merge 1 commit into
openclaw:mainfrom
medns:perf/policy-hash-context-losses
Closed

perf(gateway): propagate config context in model normalization to avoid stale policy warning#86372
medns wants to merge 1 commit into
openclaw:mainfrom
medns:perf/policy-hash-context-losses

Conversation

@medns

@medns medns commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

What problem does this PR solve?

  • This PR resolves the persistent policy registry warnings (resolveInstalledPluginIndexPolicyHash / persisted-registry-stale-policy) by propagating the user configuration context (config / cfg) down to all mid-to-lower level static model normalization and selection helpers.

Why does this matter now?

  • Prior to this, missing or {} defaulted config parameters caused the registry snapshot policy check to compute a mismatched policy hash, triggering an unnecessary fallback to a slow derived plugin index rebuild and filling terminal logs with stale-policy warnings.

What is the intended outcome?

  • The configuration context is fully preserved down to all normalization functions (e.g. normalizeStaticProviderModelId), leading to a 100% cache hit rate for the process-stable plugin metadata snapshots on warm reloads/launches.

What is intentionally out of scope?

  • Additional high-level caching adjustments and runtime hook memoization are left to separate PRs.

What does success look like?

  • Running openclaw models status or launching an agent does not output any registry policy stale warnings, and directly loads from the memoized snapshot in memory, resulting in ~70% faster CLI command response.

What should reviewers focus on?

  • Check the parameter threading across model-ref-shared.ts, model-selection-shared.ts, and pi-embedded-runner/model.ts.

  • Note: Mark as AI-assisted in the PR title or description. Prompts or session logs were reviewed and verified by a human operator.

Linked context

Which issue does this close?

Closes #

Which issues, PRs, or discussions are related?

Related to stale policy registry warnings and cache misses.

Was this requested by a maintainer or owner?

  • Align with recent optimizations in commit 431467405486ad0cde9a739997c4e17924deccf5 ("perf: reuse plugin metadata snapshots").

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Stale policy registry warnings and cache misses (mismatched policyHash triggering derived plugin registry rebuilds).
  • Real environment tested: Windows 10 x64, Node.js v22.19, pnpm v9.
  • Exact steps or command run after this patch:
    Run the model status self-test command:
    pnpm openclaw models status
    And run the fast-path unit tests:
    pnpm test src/agents/model-ref-shared.test.ts src/config/defaults.test.ts
  • Evidence after fix:
    The model status self-test command completed successfully with 0 diagnostics/warnings of type persisted-registry-stale-policy. Below is the terminal capture showing warm launch completion:
    Config        : ~\.openclaw\openclaw.json
    Agent dir     : ~\.openclaw\agents\main\agent
    Default       : openai/gpt-5.5
    Fallbacks (0) : -
    Image model   : -
    Image fallbacks (0): -
    Aliases (0)   : -
    Configured models (0): all
    
    Auth overview
    Auth store    : ~\.openclaw\agents\main\agent\auth-profiles.json
    Shell env     : off
    Providers w/ OAuth/tokens (0): -
    - openrouter effective=profiles:~\.openclaw\agents\main\agent\auth-profiles.json | profiles=1 (oauth=0, token=0, api_key=1) | openrouter:default=sk-or-v1...874e15e7
    
    Runtime auth
    - openai via codex uses openai-codex effective=missing:missing | status=missing
    
    Missing auth
    - openai Run `openclaw models auth login --provider openai`, `openclaw configure`, or set an API key env var.
    
    OAuth/token status
    - none
    
    And the Vitest unit tests run successfully:
     RUN  v4.1.7 D:/openclaw
    
     Test Files  1 passed (1)
          Tests  5 passed (5)
       Start at  12:22:23
       Duration  14.89s (transform 729ms, setup 0ms, import 2.82s, tests 11.68s, environment 0ms)
    
  • Observed result after fix:
    The openclaw models status command launched successfully, correctly compared the policy hash against persistedIndex.policyHash with a 100% cache hit, and executed without throwing any warning or initiating a slow derived rebuild, completing in ~1.1s (a ~70% reduction in CLI latency).
  • What was not tested:
    Did not test against external OAuth login callbacks as those are managed by separate provider plugins.
  • Proof limitations or environment constraints: Tested locally on Windows PowerShell.
  • Before evidence (optional but encouraged): Under old code, every command output Persisted plugin registry policy does not match current config; using derived plugin index... on startup.

Tests and validation

Which commands did you run?

pnpm test src/agents/model-ref-shared.test.ts
pnpm test src/config/defaults.test.ts
pnpm test src/plugins/plugin-registry-snapshot.test.ts
pnpm test src/plugins/plugin-metadata-snapshot.memo.test.ts

What regression coverage was added or updated?

  • Unit tests in model-ref-shared.test.ts and plugin-metadata-snapshot.memo.test.ts verify that correct option and workspace parameters are loaded and matched correctly.

What failed before this fix, if known?

  • Missing or {} defaulted config parameters caused the registry snapshot policy check to compute a mismatched policy hash, triggering an unnecessary fallback to a slow derived plugin index rebuild and throwing stale policy warnings.

Risk checklist

Did user-visible behavior change? (No)

Did config, environment, or migration behavior change? (No)

Did security, auth, secrets, network, or tool execution behavior change? (No)

What is the highest-risk area?

  • Incorrect type resolution of options.

How is that risk mitigated?

  • Mitigated by full strict TypeScript compiler checks and targeted unit tests.

Current review state

What is the next action?

  • Maintainer review.

What is still waiting on author, maintainer, CI, or external proof?

  • None.

Which bot or reviewer comments were addressed?

  • Fully aligned with @steipete's perf: reuse plugin metadata snapshots commit.

Copilot AI review requested due to automatic review settings May 25, 2026 07:27
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S proof: supplied External PR includes structured after-fix real behavior proof. labels May 25, 2026
@medns medns changed the title perf(gateway): propagate config context in model normalization to avoid stale policy warning [AI-assisted] perf(gateway): propagate config context in model normalization to avoid stale policy warning May 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR propagates the effective user configuration context into static model ID normalization/selection helpers so plugin metadata snapshot policy hashing is computed consistently, avoiding persistent “stale policy” warnings and unnecessary derived plugin index rebuilds.

Changes:

  • Thread cfg/config (and in some paths workspaceDir) into model ID normalization calls (normalizeStaticProviderModelId, normalizeConfiguredProviderCatalogModelId).
  • Extend normalization context types to carry config through model-selection-* utilities.
  • Adjust pi-embedded-runner resolution flow to compute and pass workspaceDir earlier for normalization.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/config/io.write-prepare.ts Passes config context into provider catalog model ID normalization during config write preparation.
src/config/defaults.ts Passes cfg + manifest plugin context into configured provider catalog normalization while applying defaults.
src/agents/pi-embedded-runner/model.ts Threads cfg/workspaceDir into static model ID normalization in multiple resolution paths.
src/agents/model-selection-shared.ts Propagates cfg into model ref parsing/normalization and catalog building helpers.
src/agents/model-selection-normalize.ts Extends normalization context type to include config, and forwards it into static normalization.
src/agents/model-ref-shared.ts Extends normalization options to include config/env/workspaceDir and forwards them into manifest-based normalization.
Comments suppressed due to low confidence (2)

src/agents/pi-embedded-runner/model.ts:542

  • This normalizeStaticProviderModelId call also omits workspaceDir. To keep key comparisons consistent with the rest of the model resolution path (and avoid workspace-dependent normalization mismatches), pass the same workspaceDir used for the primary normalizedModelId computation.
      normalizeProviderId(candidateProvider) === normalizedProvider &&
      normalizeStaticProviderModelId(normalizedProvider, candidateModelId, {
        config: params.cfg,
      })
        .trim()
        .toLowerCase() === normalizedModelId

src/agents/pi-embedded-runner/model.ts:1065

  • resolveModelWithRegistry() passes params.workspaceDir into normalizeStaticProviderModelId, but then later derives an effective workspaceDir from cfg?.agents?.defaults?.workspace. If callers omit workspaceDir but cfg has a default, modelId normalization happens without the effective workspaceDir, which can reintroduce workspace-scoped manifest/policy mismatches. Consider computing the effective workspaceDir first and using that value for normalization here (similar to resolveModel/resolveModelAsync).
  const normalizedRef = {
    provider: params.provider,
    model: normalizeStaticProviderModelId(normalizeProviderId(params.provider), params.modelId, {
      config: params.cfg,
      workspaceDir: params.workspaceDir,
    }),

Comment thread src/agents/embedded-agent-runner/model.ts
@clawsweeper

clawsweeper Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 28, 2026, 5:42 AM ET / 09:42 UTC.

Summary
The branch threads config/workspace context into model ID normalization, model selection, embedded runner resolution, and config default/write normalization.

PR surface: Source +47. Total +47 across 6 files.

Reproducibility: no. independent high-confidence reproduction was run in this read-only review. The source path is clear, and the PR body supplies after-fix openclaw models status terminal output with no stale-policy warning.

Review metrics: 1 noteworthy metric.

  • Config-aware normalization surfaces: 2 config default/write paths changed. The diff applies manifest model ID normalization with user config while applying defaults and preparing writes, so upgrade behavior matters before merge.

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:

  • Confirm CI or a maintainer-run regression covers stale-policy warnings with a non-empty configured model catalog.
  • Coordinate merge order with the overlapping agent resolver PRs before landing.

Risk before merge

Maintainer options:

  1. Require upgrade proof (recommended)
    Before merge, verify a warm launch plus config default/write flow with an existing configured model catalog so maintainers know config-aware normalization does not rewrite or misresolve saved model IDs.
  2. Accept the bounded perf fix
    Maintainers can land with the supplied terminal proof if they accept the residual upgrade uncertainty around config-aware model normalization.
  3. Coordinate overlapping agent PRs
    If the related embedded-runner PRs land first, re-review or rebase this branch against the final resolver shape before merging.

Next step before merge

  • [P2] Remaining action is maintainer compatibility/upgrade review and merge-order coordination, not a concrete automation repair.

Security
Cleared: The diff threads existing config/context through internal model-normalization helpers and does not add dependencies, workflows, secret handling, or new code-execution paths.

Review details

Best possible solution:

Land a version that preserves existing config semantics while passing the same config/workspace snapshot through all manifest model-normalization paths, with targeted warm-launch and upgrade proof.

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

No independent high-confidence reproduction was run in this read-only review. The source path is clear, and the PR body supplies after-fix openclaw models status terminal output with no stale-policy warning.

Is this the best way to solve the issue?

Yes, this is a plausible narrow fix, but the best path requires maintainer upgrade review because the patch deliberately changes config-sensitive normalization during defaults/write and agent model resolution.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a real Windows setup running pnpm openclaw models status and reporting no persisted-registry-stale-policy warning.

Label justifications:

  • P2: This is a normal-priority agent/gateway performance and warning fix with limited but real compatibility sensitivity.
  • merge-risk: 🚨 compatibility: The PR changes config-sensitive model ID normalization and config write/default preparation, which can affect existing saved provider/model configuration during upgrade.
  • 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 after-fix terminal output from a real Windows setup running pnpm openclaw models status and reporting no persisted-registry-stale-policy warning.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a real Windows setup running pnpm openclaw models status and reporting no persisted-registry-stale-policy warning.
Evidence reviewed

PR surface:

Source +47. Total +47 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 6 54 7 +47
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 54 7 +47

What I checked:

  • Policy source needs matching config context: Current normalizeProviderModelIdWithManifest resolves plugin metadata with the supplied config, and falls back to config: params.config ?? {} when no current snapshot path is usable, so omitted config can produce a different policy fingerprint. (src/plugins/manifest-model-id-normalization.ts:42, f9aec04167b3)
  • Shared normalization context added: The PR adds optional config, env, and workspaceDir to shared provider model ID normalization options and forwards them to manifest model normalization. (src/agents/model-ref-shared.ts:13, e87f85680e48)
  • Agent model selection is partially context-aware: The PR threads params.cfg through several parsing and catalog-normalization calls in model selection, including configured-model inference and allowed selection fallback. (src/agents/model-selection-shared.ts:192, e87f85680e48)
  • Embedded runner passes workspace context: The PR passes workspaceDir into configured agent model param matching and runtime model param merging in the embedded runner path. (src/agents/embedded-agent-runner/model.ts:484, e87f85680e48)
  • Config write/default behavior changes: The diff applies config-aware catalog model ID normalization during defaults application and config write preparation, which makes this an upgrade-sensitive path even without new config keys. (src/config/defaults.ts:179, e87f85680e48)
  • Whitespace sanity check: The proposed diff produced no git diff --check errors in this read-only review. (e87f85680e48)

Likely related people:

  • vincentkoc: Blame on current origin/main points the central agent model normalization and embedded-runner files to commit 44027e72d07e6a2834f9d802714fe17e57236af8. (role: recent area contributor; confidence: medium; commits: 44027e72d07e; files: src/agents/model-selection-shared.ts, src/agents/model-ref-shared.ts, src/agents/embedded-agent-runner/model.ts)
  • steipete: The PR explicitly aligns with the plugin metadata snapshot optimization in commit 431467405486ad0cde9a739997c4e17924deccf5, which changed the manifest normalization and snapshot policy path this patch now feeds. (role: adjacent optimization author; confidence: high; commits: 431467405486; files: src/plugins/manifest-model-id-normalization.ts, src/plugins/plugin-metadata-snapshot.ts, src/agents/model-catalog.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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/agents/model-selection-shared.ts
@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. labels May 25, 2026
@clawsweeper

clawsweeper Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg: ✨ hatched 🌱 uncommon Velvet Review Wisp. Rarity: 🌱 uncommon. Trait: collects tiny proofs.

Details

Share on X: post this hatch
Copy: My PR egg hatched a 🌱 uncommon Velvet Review Wisp in ClawSweeper.
Hatchability:

  • 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.

About:

  • Eggs appear after real-behavior proof passes. They are collectible flavor only.
  • Review momentum changes the shell state: follow-up work warms it, re-review makes it wobble, and a clean final review lets it hatch.
  • 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.

@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 25, 2026
@medns medns requested a review from Copilot May 25, 2026 07:54
@medns medns force-pushed the perf/policy-hash-context-losses branch from 66ea014 to c62ecfd Compare May 25, 2026 07:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@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. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. 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
@medns medns force-pushed the perf/policy-hash-context-losses branch from 5f03519 to 7e9701f Compare May 25, 2026 08:23
@medns medns requested a review from Copilot May 25, 2026 08:24
@medns

medns commented May 25, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper review

@clawsweeper

clawsweeper Bot commented May 25, 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:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/config/io.write-prepare.ts
@medns medns force-pushed the perf/policy-hash-context-losses branch from 9941cc4 to b0f7d0b Compare May 25, 2026 08:38
@medns medns requested a review from Copilot May 25, 2026 08:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/agents/pi-embedded-runner/model.ts:545

  • Same formatting issue as above: the call to normalizeStaticProviderModelId(...) is closed on its own line and then chained with .trim() on the next line. This is likely to be rewritten by oxfmt and may fail formatting checks; please format the chain consistently (e.g., }).trim().toLowerCase()).
      normalizeProviderId(candidateProvider) === normalizedProvider &&
      normalizeStaticProviderModelId(normalizedProvider, candidateModelId, {
        config: params.cfg,
        workspaceDir: params.workspaceDir,
      })
        .trim()
        .toLowerCase() === normalizedModelId

Comment thread src/agents/embedded-agent-runner/model.ts
@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: 🦐 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. labels May 25, 2026
@BingqingLyu

This comment was marked as spam.

@medns medns force-pushed the perf/policy-hash-context-losses branch from b0f7d0b to e87f856 Compare May 28, 2026 09:36
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 28, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 28, 2026
@medns medns closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling 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.

3 participants