Skip to content

feat(models): make per-agent model allowlist explicit; aliases/defaults no longer restrict#110888

Merged
steipete merged 1 commit into
mainfrom
claude/model-allowlist-explicit
Jul 18, 2026
Merged

feat(models): make per-agent model allowlist explicit; aliases/defaults no longer restrict#110888
steipete merged 1 commit into
mainfrom
claude/model-allowlist-explicit

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

agents.defaults.models did three jobs at once: per-model config (aliases/params), default/fallback selection, AND the --model override allowlist. Because an EMPTY map meant allow-any and ANY entry meant a closed allowlist, the two most innocent commands — models set <default> and models aliases add <name> <ref> — silently flipped an agent from "any model allowed" to "locked down", so a previously-working --model openai/gpt-5.6-sol started failing with "not allowed for agent", with nothing explaining why. Found by the R5 QA campaign.

Why This Change Was Made

The allowlist should be an explicit, opt-in restriction — not a side effect of naming an alias or picking a default. This separates the three concerns and makes the restriction its own config surface, while preserving existing installations' behavior across upgrade.

User Impact

  • New explicit key agents.defaults.modelPolicy.allow (and per-agent agents.list[].modelPolicy.allow) owns model-override restriction. Absent/empty ⇒ allow-any. agents.defaults.models is now metadata + default/fallback ordering only and no longer restricts overrides. models set/aliases add never lock out overrides.
  • Behavior-preserving migration: openclaw doctor --fix (and the first config write) stamp modelPolicy.allow from an existing effective agents.defaults.models restriction and set a migration marker, so restricted installs stay restricted. A shared computeModelPolicyAllowlist helper is used by runtime, doctor, and the config writer so pre- and post-migration behavior is identical.
  • Safe upgrade read-path: before the migration runs, the runtime interprets an unmarked legacy default-map restriction as the allowlist (marker-gated, security-preserving) so a restriction is never silently dropped on first startup after upgrade. Only agents.defaults.models is a legacy allowlist — per-agent models maps are metadata-only and never become a restriction.
  • Clear rejection guidance points users at modelPolicy.allow (not the legacy map) for repair. Configured fallbacks are failover-only and are not selectable as explicit overrides unless explicitly allowed. An explicit modelPolicy: {} is an allow-any opt-in and is honored consistently across runtime, write, and cron/agent-scope inheritance.

Evidence

  • Live dev-gateway proof: after models aliases add + models set, --model openai/gpt-5.6-sol succeeds (the original QA trap is gone); setting modelPolicy.allow to clawrouter-only then rejects openai with a message naming the key; a live legacy-config doctor --fix stamps modelPolicy.allow from the legacy map and validates.
  • Tests: policy/visibility, doctor migration (incl. version-bump-then-migrate and upgrade fail-open regressions), configure/picker seeding, per-agent inheritance, cron inheritance preservation, fallback authorization separation, and empty-{} semantics across all boundaries.
  • Autoreview (codex gpt-5.6-sol, xhigh): clean after a deep multi-round review that surfaced and closed real correctness/security edges (fallback-bypass, upgrade fail-open, per-agent-metadata misclassification, empty-policy consistency). Config contract aligned: schema, schema-help, docs, and baselines updated together. git diff --numstat shows the per-agent legacy path was deleted, not added.

This is a compatibility-sensitive config-surface change (new modelPolicy.allow key + doctor migration); existing restricted configs are preserved via marker-gated migration.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord gateway Gateway runtime scripts Repository scripts commands Command implementations agents Agent runtime and tooling extensions: clawrouter Extension: clawrouter size: XL maintainer Maintainer-authored PR labels Jul 18, 2026
@steipete steipete self-assigned this Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8371f52242

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/model-selection-shared.ts Outdated
Comment on lines +1510 to +1515
if (params.agentId) {
const normalizedAgentId = normalizeAgentId(params.agentId);
const agent = params.cfg?.agents?.list?.find(
(entry) => normalizeAgentId(entry.id) === normalizedAgentId,
);
if (hasExplicitModelPolicyAllow(agent?.modelPolicy)) {

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.

P2 Badge Apply per-agent policy when patching session models

When an agent’s modelPolicy.allow differs from the default policy, Gateway sessions.patch validates against the wrong scope: src/gateway/sessions-patch.ts:625-631 calls resolveAllowedModelRef without the already-resolved sessionAgentId, so this new per-agent branch is never entered. Consequently, the Control UI/session API rejects models permitted only for that agent, while models denied by that agent but permitted globally are accepted and persisted before runtime later reverts them; per-agent aliases are likewise unavailable on this path. Propagate agentId through resolveAllowedModelRef, its alias index, and its status check.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 18, 2026
@clawsweeper

clawsweeper Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 18, 2026, 4:06 PM ET / 20:06 UTC.

Summary
The branch separates model-override authorization from per-model aliases and metadata by adding explicit default and per-agent modelPolicy.allow configuration plus migration and documentation updates.

Reproducibility: no. The described regression has a plausible gateway/config path and targeted tests, but no inspectable final-head live transcript or artifact establishes the before/after result.

Review metrics: 1 noteworthy metric.

  • Persistent configuration surfaces: 2 policy scopes added, 1 migration marker added. Default and per-agent authorization semantics plus persisted migration state can affect existing configurations and provider access after upgrade.

Stored data model
Persistent data-model change detected: database schema: src/config/schema.labels.ts, migration/backfill/repair: src/agents/agent-scope-config.ts, migration/backfill/repair: src/agents/model-selection-shared.ts, migration/backfill/repair: src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts, migration/backfill/repair: src/config/config.meta-timestamp-coercion.test.ts, migration/backfill/repair: src/config/io.meta.test.ts, and 16 more. Migration or upgrade compatibility proof is recorded; maintainers should verify it before merge.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until 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:

  • Attach a redacted terminal transcript or recording from the final head showing alias/default writes leave an unrelated override allowed.
  • [P1] Show an explicit modelPolicy.allow rejection and a legacy config doctor --fix migration with the preserved allowlist.
  • After updating the PR body, request a fresh review with @clawsweeper re-review if automatic re-review does not occur.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR describes real dev-gateway checks but supplies no inspectable after-fix terminal output, recording, screenshot, linked artifact, or redacted logs; add redacted proof for the final head before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Existing installations that relied on agents.defaults.models as an override restriction must retain that restriction through config writes, doctor migration, $include resolution, and first startup after upgrade.
  • [P1] The new policy governs model selection and provider access paths; merge review should confirm the exact head preserves authorization consistently across gateway sessions, directives, cron, picker/status flows, and provider aliases.

Maintainer options:

  1. Require final-head upgrade and runtime proof (recommended)
    Before merge, attach redacted evidence showing a legacy restricted config remains restricted before migration, migrates correctly with doctor, and aliases/default changes do not restrict an otherwise allowed override.
  2. Accept the migration contract explicitly
    A maintainer may accept the remaining upgrade risk only after confirming that the marker-gated legacy interpretation is the intended public compatibility policy.
  3. Pause for a narrower contract decision
    Pause this branch if maintainers do not want a new persistent per-agent authorization configuration surface.

Next step before merge

  • [P1] A maintainer must accept the new public policy and migration contract; the remaining contributor action is to provide inspectable final-head real behavior proof.

Maintainer decision needed

  • Question: Should OpenClaw adopt agents.*.modelPolicy.allow as the permanent public authorization contract and preserve legacy default-map restrictions through the proposed marker-gated migration?
  • Rationale: This introduces a persistent public configuration and migration contract whose compatibility and authorization semantics require owner acceptance beyond a routine code review.
  • Likely owner: steipete — The available review context ties this person to the current model-policy proposal and its stated upgrade contract.
  • Options:
    • Adopt explicit policy contract (recommended): Approve the new explicit policy direction after final-head upgrade proof confirms legacy restrictions remain fail-closed until migrated.
    • Retain legacy map contract: Keep agents.defaults.models as the authorization surface and narrow this work to diagnostics or documentation improvements.
    • Split the migration proposal: Merge only a bounded compatibility-safe precursor after defining the permanent configuration contract separately.

Security
Cleared: The patch changes authorization semantics but the supplied latest-head context shows targeted follow-up for reported fail-open paths; no additional concrete security or supply-chain defect is established from the available evidence.

Review details

Best possible solution:

Land only after a maintainer accepts the explicit persistent policy contract and inspectable, redacted gateway evidence proves unrestricted alias/default changes, explicit rejection, and legacy migration behavior on the final head.

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

No. The described regression has a plausible gateway/config path and targeted tests, but no inspectable final-head live transcript or artifact establishes the before/after result.

Is this the best way to solve the issue?

Unclear. Separating aliases and defaults from authorization is a coherent solution, but the permanent public config and upgrade semantics need maintainer approval and final-head proof before it can be called the best fix.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1cacb12c4d7b.

Label changes

Label changes:

  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.

Label justifications:

  • P2: The change addresses a meaningful but bounded model-selection/configuration problem and requires compatibility review before release.
  • merge-risk: 🚨 compatibility: The branch changes the meaning of an existing model map and adds a marker-gated migration for persisted user configuration.
  • merge-risk: 🚨 auth-provider: The new allowlist authorizes explicit model overrides and therefore affects which configured provider/model routes users may select.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR describes real dev-gateway checks but supplies no inspectable after-fix terminal output, recording, screenshot, linked artifact, or redacted logs; add redacted proof for the final head before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Current branch scope: The supplied PR context shows an open, cleanly mergeable branch that adds AgentModelPolicyConfig, a config migration marker, runtime policy resolution, doctor/config-write migration handling, and broad docs/test updates. (src/config/model-policy-allowlist-migration.ts:1, 13bf53398ddd)
  • Prior blockers addressed in follow-up head: The latest head was force-pushed after the earlier review findings concerning session patch scope, primary/fallback behavior, include-backed migration, blank policy entries, and status alias scope; the provided changed-file context includes targeted runtime and regression-test changes in those areas. (src/agents/model-selection-shared.ts:1, 13bf53398ddd)
  • Config compatibility surface: The branch introduces explicit agents.defaults.modelPolicy.allow, per-agent policy support, and meta.migrations.modelPolicyAllowlist; existing restrictive configurations depend on correct migration and runtime interpretation. (src/config/types.agent-defaults.ts:46, 13bf53398ddd)
  • Real-proof gap: The PR body reports a dev-gateway exercise, but the supplied discussion contains only approval commands and no terminal transcript, recording, screenshot, redacted log, or linked artifact that independently shows the described before/after behavior. (13bf53398ddd)
  • Current-main and release status: The supplied repository state identifies current main as 1cacb12c4d7b693dd08485d87695376868392287 and latest release as v2026.7.1; this open PR head is not represented as merged or shipped. (1cacb12c4d7b)

Likely related people:

  • steipete: The available history identifies this person as the sole author of the proposed model-policy migration and the person who supplied the security-sensitive-change approvals; repository-history ownership could not be independently expanded in this read-only environment. (role: current model/config change contributor; confidence: low; commits: 13bf53398ddd; files: src/config/model-policy-allowlist-migration.ts, src/agents/model-selection-shared.ts, src/commands/doctor/shared/legacy-config-migrations.runtime.models.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.
Review history (1 earlier review cycle)
  • reviewed 2026-07-18T19:28:03.207Z sha 8371f52 :: needs real behavior proof before merge. :: [P2] Apply the per-agent policy when patching session models

@steipete
steipete force-pushed the claude/model-allowlist-explicit branch 2 times, most recently from 3557022 to 5a7a1d3 Compare July 18, 2026 19:47
@steipete

Copy link
Copy Markdown
Contributor Author

/allow-security-sensitive-change 5a7a1d3

@steipete

Copy link
Copy Markdown
Contributor Author

/allow-dependencies-change 5a7a1d3

@clawsweeper clawsweeper Bot removed the rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. label Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a7a1d32f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}

/** Build allowed model keys/catalog entries after provider wildcards and fallbacks. */
/** Build explicit override authorization plus configured automatic fallback keys. */

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.

P1 Badge Keep configured primaries outside override filtering

When the configured primary is outside a wildcard policy—for example, primary anthropic/claude-sonnet-4-6 with modelPolicy.allow: ["openai/*"]—this function omits the primary from allowedKeys and allowedCatalog. Both src/agents/command/model-selection.ts:341 and src/auto-reply/reply/model-selection.ts:437 then call resolveSelection for an ordinary run with no override, so OpenClaw silently substitutes the first allowed OpenAI model or aborts when no catalog row is available, even though the new contract defines this as an override-only allowlist. Preserve the configured primary for initial selection independently of explicit override authorization.

Useful? React with 👍 / 👎.

Comment thread src/config/io.write.ts
Comment on lines +204 to +208
const stampedOutputConfig = stampConfigVersion(
outputConfig,
options.lastTouchedVersionOverride,
snapshot.exists ? snapshot.parsed : null,
);

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.

P1 Badge Migrate allowlists from the resolved include snapshot

When a legacy agents.defaults.models restriction is owned by a nested $include, snapshot.parsed contains only the include directive, not the resolved model map. The write therefore finds no legacy refs but still stamps meta.migrations.modelPolicyAllowlist; on the next read, that marker makes computeModelPolicyAllowlist ignore the included legacy map, silently changing the installation to allow-any after any unrelated config write. Detect the legacy restriction from the resolved/source snapshot while preserving the authored include structure.

Useful? React with 👍 / 👎.

@steipete
steipete force-pushed the claude/model-allowlist-explicit branch from 5a7a1d3 to afc6e60 Compare July 18, 2026 19:57
@steipete

Copy link
Copy Markdown
Contributor Author

/allow-security-sensitive-change afc6e60

@steipete

Copy link
Copy Markdown
Contributor Author

/allow-dependencies-change afc6e60

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: afc6e60f67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 1168 to 1170
allowAny: true,
allowedCatalog: catalog,
allowedKeys: catalogKeys,

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.

P1 Badge Keep unresolvable policy entries fail-closed

When a schema-valid policy contains only blank refs, such as modelPolicy.allow: [" "], parseConfiguredModelVisibilityEntries treats the array as restrictive but every ref is skipped; this branch then converts the policy to allowAny. Callers that omit defaultModel, notably the x-openclaw-model check in src/gateway/http-utils.ts, consequently permit arbitrary model overrides despite a non-empty policy. Reject blank entries during validation or preserve the explicit policy as deny-all when none resolve.

Useful? React with 👍 / 👎.

return acc;
}, {});
const allowed = Object.keys(cfg.agents?.defaults?.models ?? {});
const allowed = [...resolveConfiguredModelPolicyAllow({ cfg, agentId: workspaceAgentId }).refs];

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.

P2 Badge Resolve status policy aliases in the agent scope

When openclaw models status --agent research reads a per-agent policy such as allow: ["approved"], where approved exists only in that agent's models map, this line adds the alias to allowed but the alias index below is built without workspaceAgentId. resolveStatusModelRef therefore interprets it as DEFAULT_PROVIDER/approved, causing the auth overview to inspect the wrong provider and potentially omit missing auth for the actual allowed model. Build the status alias index with the selected agent id.

Useful? React with 👍 / 👎.

@steipete
steipete force-pushed the claude/model-allowlist-explicit branch from afc6e60 to 13bf533 Compare July 18, 2026 20:03
@steipete

Copy link
Copy Markdown
Contributor Author

/allow-security-sensitive-change 13bf533

@steipete

Copy link
Copy Markdown
Contributor Author

/allow-dependencies-change 13bf533

@clawsweeper clawsweeper Bot added the rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. label Jul 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13bf53398d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

catalog: params.catalog,
defaultProvider: params.defaultProvider,
defaultModel: params.defaultModel,
agentId: params.agentId,

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.

P2 Badge Resolve session_status aliases in the agent scope

When an agent's modelPolicy.allow references an alias defined only in that agent's models map, this newly agent-scoped policy rejects the same alias through session_status(model=...): src/agents/tools/session-status-tool.ts:461-464 builds its parsing alias index without params.agentId, while the policy at lines 474-483 now resolves the alias in the agent scope. The input is therefore parsed as <current-provider>/<alias> and fails policy.allowsKey instead of selecting the policy-approved target; pass the agent id to the tool's alias index as well.

Useful? React with 👍 / 👎.

@steipete
steipete force-pushed the claude/model-allowlist-explicit branch from 13bf533 to c8a8048 Compare July 18, 2026 20:34
@steipete

Copy link
Copy Markdown
Contributor Author

/allow-security-sensitive-change c8a8048

@steipete

Copy link
Copy Markdown
Contributor Author

/allow-dependencies-change c8a8048

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8a80486b1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1518 to +1522
if (hasExplicitModelPolicyAllow(agentPolicy)) {
return {
refs: agentPolicy?.allow ?? [],
configPath: AGENT_MODEL_POLICY_ALLOW_CONFIG_PATH,
repairConfigPath: AGENT_MODEL_POLICY_ALLOW_CONFIG_PATH,

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.

P2 Badge Resolve HTTP override aliases in the agent scope

When a per-agent policy allows an agent-local alias such as modelPolicy.allow: ["approved"], OpenAI-compatible chat/responses requests using x-openclaw-model: approved are rejected even though /model approved is accepted. src/gateway/http-utils.ts:147-166 parses the header directly with parseModelRef, so it checks <default-provider>/approved against the newly agent-scoped policy instead of resolving approved through that agent's alias index; resolve the header with the same agent-scoped alias semantics before applying policy.allowsKey.

Useful? React with 👍 / 👎.

@steipete
steipete merged commit 09a64f7 into main Jul 18, 2026
120 checks passed
@steipete
steipete deleted the claude/model-allowlist-explicit branch July 18, 2026 20:42
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

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

Labels

agents Agent runtime and tooling channel: discord Channel integration: discord commands Command implementations docs Improvements or additions to documentation extensions: clawrouter Extension: clawrouter gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. scripts Repository scripts 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.

1 participant