Commit Graph

10259 Commits

Author SHA1 Message Date
Peter Steinberger
b9377f6048 fix(codex): enforce native MCP tool access (#116054)
* fix(codex): enforce native MCP tool access

* chore: remove prerelease changelog entry

* chore: restore changelog to main

* refactor(codex): build MCP server patches from entries
2026-07-29 17:06:49 -04:00
Vincent Koc
83d725761f docs(hooks): clarify inbound claim ownership (#116082)
Refs #109353
2026-07-30 05:02:50 +08:00
Frank Yang
511ecd9dba fix(plugins): expose inbound message id before dispatch (#112359)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:26:28 +08:00
salvormallow
73b5e7aab4 fix(hooks): save memory on automatic session rollover (#61675)
* fix(hooks): persist memory on session rollover

Co-authored-by: salvormallow <15044561+salvormallow@users.noreply.github.com>

* fix(hooks): persist memory on automatic session reset

* fix(hooks): keep auto-reset reason internal

* fix(hooks): retain auto-reset memory admission

* fix(hooks): make session rollover return explicit

* test(hooks): track session memory temp dirs

* fix(hooks): satisfy session memory return contract

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:13:26 +08:00
Peter Steinberger
d6f9affe79 feat(cli): run agent exec against the ambient config, composed in memory (#116038)
* feat(cli): run agent exec against the ambient config, composed in memory

Exec previously ignored the operator's config entirely, so a one-shot turn
could not reach configured providers, credentials, or agentRuntime harness
selection. It now layers config the way other folder-scoped coding CLIs do.

The composed config is published as this process's runtime snapshot rather
than serialized to a temp file and re-read through OPENCLAW_CONFIG_PATH. The
snapshot is the only in-process config cache, so the file only ever fed it --
while writing env-substituted provider keys to disk where the run's own exec
tool could read them.

* fix(cli): resolve exec stored credentials from the configured agent dir

* chore(scripts): allow agent exec the file-scoped config loader at its process boundary

* test(cli): cover the exec credential default and pinned-config flags
2026-07-29 15:38:27 -04:00
mikasa
d2f2123da5 fix #95351: [Feature]: Generic JSONL line-parsing hook for CliBackendPlugin (native tool-card support beyond claude-stream-json) (#95386)
* feat(plugin-sdk): add CLI backend JSONL parser hook

* fix(test): isolate non-git workspace fixtures

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:37:39 +08:00
Stellar鱼
42e23c11e0 feat(plugins): allow per-turn tool narrowing in prompt hooks (#114151)
* feat(plugins): allow per-turn tool narrowing in prompt hooks

* fix(hooks): keep prompt tool policy baseline internal

* fix(test): track active tools in embedded session fixture

* test(agents): preserve active tool fixture state

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:28:45 +08:00
Vincent Koc
8a4f891450 docs(hooks): mark pairing hook observation-only (#116055) 2026-07-30 03:27:36 +08:00
Peter Steinberger
03a2c8208d docs(control-ui): document composer capability menu (#115858)
* docs(control-ui): document composer capability menu

* docs(control-ui): explain tool access discovery states

* docs(map): regenerate docs map
2026-07-29 15:26:56 -04:00
Peter Steinberger
ca07207649 docs(security): add safe Gmail reader setup (#116041)
* docs(security): add safe Gmail reader setup

* docs: leave release notes to release flow

* docs: refresh documentation map
2026-07-29 15:07:35 -04:00
Josh Lehman
6beaff450e fix(codex): avoid transcript mirror snapshot churn (#115070) 2026-07-29 11:59:14 -07:00
Ryan Hughes
9560e17185 feat(hooks): add persistent hook session mode (#75918)
* feat(hooks): add explicit persistent sessions

* fix(hooks): validate persistent mapping session keys

* chore: leave persistent hooks note to release process

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 02:57:28 +08:00
Peter Steinberger
3f4d65a672 feat(harness): report copilot code-mode engagement on the attempt result (#115913)
* feat(harness): report copilot code-mode engagement on the attempt result

* test(copilot): prove code-mode engagement through the production tool bridge

* docs: describe the normalized codeModeEngaged value for native harnesses
2026-07-29 14:44:15 -04:00
RogueL90
499d48edbb cron: reject webhook URLs with embedded credentials (#51822)
* cron: reject webhook URLs with embedded credentials

* fix(cron): reject credential-bearing webhook URLs

* chore: leave cron webhook note to release process

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 02:32:32 +08:00
Peter Steinberger
e80fe942c8 fix(gateway): stop start-time repair from retargeting managed services (#115935) 2026-07-29 13:41:19 -04:00
Naka Masato
68dbf92281 fix(plugins): scope Codex relay with tool matchers (#109603)
* fix(plugins): scope Codex relay matchers

Co-authored-by: Masato Naka <masatonaka1989@gmail.com>

* fix(plugins): reject sparse tool hook matchers

* test(plugins): cover mixed relay matcher scopes

* fix(plugins): fail closed on invalid policy matchers

* test(plugins): prove composed relay policy scope

* fix(plugins): keep matcher scope internal

* fix(plugins): satisfy matcher static checks

* fix(plugins): enforce canonical tool hook matchers

* fix(codex): project native hook matcher aliases

* fix(plugins): scope Codex relay with tool matchers

* chore: keep release changelog maintainer-owned

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:39:08 +08:00
Harjoth Khara
895b691c55 fix(daemon): refuse duplicate launchd gateway managers (#97285)
* fix(daemon): block duplicate launchd owners

Co-authored-by: Harjoth Khara <harjoth.khara@gmail.com>

* fix(ci): satisfy launchd docs and lint gates

* fix(ci): remove unused launchd exports

* docs: refresh gateway map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 13:31:22 -04:00
clawSean
864259486b fix(sms): isolate validated webhook quotas per sender (#104862)
* fix(sms): isolate validated webhook quotas per sender

* fix(sms): isolate validated webhook quotas per sender

---------

Co-authored-by: clawSean <260045960+clawSean@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:23:24 +08:00
Peter Steinberger
d7d3fc5dad feat(ui): enable tool-loop detection from Labs (#115983)
* feat(ui): add tool loop detection lab

* docs(tools): mention loop detection lab
2026-07-29 13:21:52 -04:00
Masato Hoshino
458bb58ae5 fix(voice-call): pin Twilio webhook verification to the configured public path (#112800)
* fix(voice-call): pin Twilio webhook verification to the configured public path

buildTwilioVerificationUrl overwrote the configured publicUrl path with the
incoming request path, so behind a path-rewriting reverse proxy the
reconstructed verification URL no longer matched the URL Twilio signed and
valid webhooks were rejected. Use the configured public path (keep the request
query), mirroring the Plivo sibling fixed in #112559. Restores callback-path
binding and adds proxy-prefix accept + local-path reject regression tests.

* fix(voice-call): pin Twilio verification to public URL path

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:08:38 +08:00
Eden
601a405430 fix(channels): mark durable webhook acceptance on Zalo, Google Chat, SMS, Feishu, Nextcloud Talk, and Synology Chat (#115586)
* fix(channels): extend the durable-acceptance marker to zalo, googlechat, and sms

* fix(feishu): mark durable webhook acceptance

* fix(channels): extend the durable-acceptance marker to nextcloud-talk and synology-chat

* fix(channels): extend the durable-acceptance marker to zalo, googlechat, and sms

* fix(feishu): mark durable webhook acceptance

* fix(channels): extend the durable-acceptance marker to nextcloud-talk and synology-chat

* fix(channels): carry durable webhook admission results

* docs(changelog): note durable webhook acceptance

* test(channels): tighten webhook admission types

* chore: leave release changelog to release prep

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:07:08 +08:00
Brandon
bfc99c97c5 docs(plugins): clarify hook runtime activation (#77629)
* docs(plugins): clarify hook runtime activation

* docs(plugins): correct hook startup activation guidance

* docs(plugins): clarify hook runtime activation

* docs(plugins): clarify hook runtime startup

Co-authored-by: Brandon Zarnitz <bzarnitz13@gmail.com>

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:02:31 +08:00
Sascha Kuhlmann
814b9f6e36 fix(hooks): bound agent runner admission (#104712)
* fix(hooks): gate agent admission on runner entry

Co-authored-by: Sascha Kuhlmann <117685070+coolmanns@users.noreply.github.com>

* fix(hooks): bound agent runner admission

Co-authored-by: Sascha Kuhlmann <117685070+coolmanns@users.noreply.github.com>

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:01:46 +08:00
Peter Steinberger
ca36be96e0 docs: add cross-client media playback guide (#116005)
* docs: add media playback guide

* docs: complete media playback glossary
2026-07-29 13:00:40 -04:00
Peter Steinberger
dc60a9442d feat(talk): support GPT-Live over gateway relay (#115831)
* feat(talk): add GPT-Live gateway relay peer

* fix(talk): ignore duplicate GPT-Live sideband audio

* fix(openai): harden GPT-Live relay startup

* fix(deps): replace vulnerable werift ip helper

* fix(deps): scope werift ip override version

* fix(openai): normalize relay startup errors

* test(ci): register GPT-Live gateway live shard

* fix(talk): tighten GPT-Live relay readiness

* fix(talk): keep relay override helper private

* fix(talk): resolve relay readiness with launch model

* fix(openai): preserve GPT-Live media clock

* fix(talk): align GPT-Live relay readiness and framing

* fix(openai): expire pending GPT-Live reservations

* fix(openai): harden GPT-Live delegation audio

* style(openai): satisfy RTP reorder lint
2026-07-29 12:54:23 -04:00
Peter Steinberger
c87e545c88 fix(ui): rename the Memory Palace browser to Memory Wiki and document it (#115954)
* fix(ui): rename the Memory Palace browser to Memory Wiki and document it

* refactor(memory-wiki): drop the old memory-palace module files

* docs: refresh generated docs map

* test(ui): align dream-diary hub-tab assertion with the wiki sub-tab id

* docs: describe memory wiki clustering behavior accurately

* docs(memory-wiki): record the wiki.overview rename decision at the registration site

* test(ui): query the Agents channels hub tab by tab role after the hub-tabs refactor
2026-07-29 12:51:37 -04:00
Peter Steinberger
d16e33e08e fix: restore trustworthy end-to-end QA and cross-channel delivery (#115404)
* fix(qa): repair verified end-to-end and channel regressions

* fix(gateway): make interrupted restart recovery lifecycle-safe

* test(heartbeat): target the canonical recovery session store

* fix(gateway): prioritize durable restart recovery before heartbeat

* fix(qa): preserve safe restart recovery and channel expiry

* fix(qa): fail closed and fence restart recovery

* test(agents): isolate restart recovery timing

* test(agents): prove actual restart retry timing

* fix(qa): report incompatible profile scenarios

* fix(scripts): resolve symlinked docker scheduler entrypoints

* fix(qa): require fresh native test evidence

* fix(heartbeat): fence active restart recovery delivery

* fix(gateway): consume untargeted restart acknowledgements

* fix(qa): satisfy exhaustive hosted validation gates

* fix(agents): fence stopped restart recovery dispatch

* style(agents): format restart recovery lifecycle regression

* test(gateway): isolate context prewarm sidecar lifecycle

* test(qa): make scenario process timeout cleanup deterministic

* fix(qa): stamp synthetic gateway configs with current version

* fix(openai): preserve vision capabilities in stale model catalogs

* test(qa): align profile channel rejection with current main

* fix(openai): forward supported moderation for image edits

* fix: restore latest-main CI and image edit documentation

* fix(qa): retain relocated code-mode evidence validation

* fix(openai): expose GPT-5.4 vision in static catalog

* fix(pricing): honor explicit model cost overrides

* test(pricing): keep isolated provider regressions deterministic

* fix(openai): inherit transport for discovered static models

* fix(gateway): honor agent-owned static image capabilities

* test(gateway): preserve prepared-snapshot attachment races

* test(gateway): isolate subagent persistence failure injection

* test(gateway): exercise concurrent voice replay admission

* fix(gateway): restore stale model image capabilities

* fix(agents): publish configured model vision capabilities

* fix(agents): isolate detached media transcript ownership

* test(agents): preserve generic transcript lock regression

* fix(gateway): require proven static model route identity

* fix(qa): accept bounded full-size generated image attachments

* fix(qa): require fresh script producer evidence

* test(qa): prove native E2E scenario execution
2026-07-29 12:45:27 -04:00
Peter Steinberger
cc2ba80639 docs: expand Telegram Mini App guide (#115981) 2026-07-29 12:39:54 -04:00
Peter Steinberger
ea967be0df feat(gateway): add loopback locality controls (#115959)
* feat(gateway): add loopback locality controls

* fix(gateway): keep loopback auth delays enforced under concurrency

The pending-timer cap let an attacker park cheap failures in every slot and then guess without penalty. Delays now key off a per-key deadline, so parallel guesses wait out the same escalating penalty and are still bounded by the max delay.

* fix(gateway): share one loopback penalty timer per key

Concurrent failures on a key now share a single timer and deadline instead of allocating one per in-flight request. Also corrects the security doc: the delay raises the cost of repeated guessing from one source, but credentials are compared before the failure response is delayed, so it is not a defense against parallel fan-out.

* docs(gateway): record why loopback delay stays post-verification

* docs: refresh generated docs map

* docs: refresh plugin SDK API baseline

* test: update loopback locality CI expectations
2026-07-29 12:25:57 -04:00
Sascha Kuhlmann
819961a292 fix(hooks): avoid implicit hook delivery targets (#100486)
* fix(gateway): bind hook delivery before scheduling

Co-authored-by: Sascha Kuhlmann <117685070+coolmanns@users.noreply.github.com>

* test(cli): make stderr tail fixture deterministic

* test(cli): allow loaded runners to start

* fix(gateway): narrow hook delivery binding

Co-authored-by: Sascha Kuhlmann <117685070+coolmanns@users.noreply.github.com>

* fix(gateway): keep hook delivery normalization internal

* style(gateway): format hook delivery helper

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 23:14:46 +08:00
Peter Steinberger
34e81ca0dc feat(codex): support the openai-api-curated marketplace wire name (#115955) 2026-07-29 11:07:16 -04:00
Vincent Koc
41f118cec3 fix(plugins): forward tool cancellation to hooks (#115817)
* fix(plugins): forward tool cancellation to hooks

* test(plugins): prove hook cancellation propagation
2026-07-29 22:54:01 +08:00
Peter Steinberger
53815217e9 fix(memory): session backfill drains and rolls back reversibly (#115926)
* fix(memory): complete reversible session backfill

* refactor(memory): split backfill lifecycle helpers

* fix(memory): break backfill lifecycle import cycle

* fix(memory): keep lifecycle contract exports minimal
2026-07-29 10:48:16 -04:00
Colin Johnson
306c02af57 feat(ui): preview session workspace images (#95956)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 09:22:46 -04:00
Peter Steinberger
095f30ae26 feat(skills): review interrupted deep turns in experience review (#115887)
* feat(skills): review interrupted deep turns in experience review

* test(skills): stabilize experience-review live eval and cover interrupted turns
2026-07-29 09:11:02 -04:00
Peter Steinberger
40dafc5c33 refactor: replace context-engine retry proxy with declared params (#115872)
* refactor(context-engine): remove legacy host-key retry proxy

* refactor(context-engine): declare accepted host parameters

* fix(context-engine): preserve engine adapter receivers

* refactor(plugins): tighten context-engine compat record

* refactor(context-engine): inline compat window lookup

* docs(plugins): align context-engine removal diagnostic

* test(context-engine): declare harness proof parameters
2026-07-29 08:37:08 -04:00
synth
151c549494 fix(browser): uploads fail when the browser runs on a remote node (#115291)
* fix(browser): resolve upload paths on the owning browser node, not the Gateway

When a browser session is proxied to a remote node, the upload action
previously ran resolveExistingUploadPaths on the Gateway, pinning paths
to a filesystem the node cannot see and rejecting node-local files. The
node-side /hooks/file-chooser route already re-resolves paths against
its own filesystem, so skip Gateway-local resolution whenever the
request is proxied and forward the requested paths as-is.

Fixes openclaw/openclaw#115251

* fix(browser): transfer uploads to remote browser nodes

* fix(browser): normalize upload abort errors

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 20:31:46 +08:00
Yuval Dinodia
edf4aca7bc fix(agents): apply_patch destroys an existing file when a patch creates that path (#114911)
* fix(agents): stop apply_patch from silently overwriting existing files

An "*** Add File:" hunk wrote its target unconditionally. When the path
already existed, apply_patch replaced the entire file, returned Success,
and listed the path under "added", so neither the model nor the UI got
any signal that existing content had been destroyed. The "*** Move to:"
destination of an update hunk had the same gap and reported the clobbered
path as merely modified.

The add and move-to branches now check the destination through the patch
file ops before writing and fail closed when it exists. Routing the check
through fileOps keeps it correct on all three backends (workspace-scoped
fs-safe root, raw fs, sandbox bridge). The check runs per hunk in patch
order, so deleting a path earlier in the same patch and recreating it
still works.

* fix(agents): make apply_patch destination creation atomic

The previous guard checked that an add or move-to destination was absent
and then wrote it. A competing writer could create the path in that gap,
after which the write still replaced it, so the no-clobber guarantee did
not hold under contention.

Destination creation now goes through a single exclusive create-if-absent
operation on every patch backend: Root.create for the workspace-scoped
default, an O_EXCL write for the raw filesystem, and a new pinned create
operation in the sandbox mutation helper that opens the target with
O_CREAT|O_EXCL and reports a reserved exit code when it already exists.
PatchFileOps drops its separate existence check.

Resolving the host ops behind an early return removes the repeated
workspaceOnly branch inside each operation and the optional-call dance
that let a missing root silently skip a write.

* fix(agents): complete atomic apply-patch creation

* fix(agents): preserve raced create replacements

* fix(agents): handle fs-safe patch collisions

* fix(agents): publish sandbox creates atomically

* test(agents): cover exclusive create provenance rollback

* fix(agents): use typed exclusive-create signal

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 20:17:54 +08:00
Peter Steinberger
bfb7ff189e docs(codex): replace stale app/list wording with app/installed (#115867) 2026-07-29 08:09:44 -04:00
Peter Steinberger
af70829cdf refactor(ui): move Agent Defaults entry from the sidebar into the Agents page (#115836)
* refactor(ui): move Agent Defaults entry from the sidebar into the Agents page

* fix(ui): keep Agent Defaults searchable
2026-07-29 06:30:40 -04:00
Peter Steinberger
662abec754 feat(gateway): push session PR indicators to subscribed clients (#115643)
* feat(gateway): push session PR indicators to subscribed clients

* test(gateway): fix PR indicator drift

* chore(protocol): allowlist PR-indicator event for native apps (Control UI surface)

* test: align PR indicator lifecycle coverage

* fix(ui): scope session PR store listeners to active watchers
2026-07-29 06:30:01 -04:00
Peter Steinberger
986e5d1758 refactor(channels): share ingress retention defaults (#115824) 2026-07-29 06:24:30 -04:00
stevenlee-oai
a00438a867 fix(codex): restore connected apps for token-authenticated runs (#115075)
* fix(codex): restore connected apps for token-authenticated runs

* fix(codex): keep app inventory protocol types private

* fix(codex): align native runtime with Codex 0.146.0

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): clean up latest app-server integration

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): keep internal protocol types private

* fix(ci): repair current main Codex landing gates

* fix(ci): format inherited code mode matrix

* fix(codex): reconcile native app-server contracts with main

Prepare a verified GitHub-hosted mainline merge while preserving the reviewed Codex 0.146.0 fixes and canonical OpenAI authentication.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): keep QA evidence in its owning plugin

Resolve the current-main Code Mode test rename without resurrecting the retired core test path.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): enforce canonical OpenAI app-server auth

Reject retired provider aliases without runtime compatibility, direct operators to the doctor migration, and remove the redundant OpenAI API-key predicate.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* chore(codex): reconcile latest main dependency graph

Preserve current main dependency changes while preparing the original Codex PR for an ancestry-preserving signed mainline merge.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): unify bundled Codex 0.146 runtimes

Keep the ACP adapter on the same 0.146.0 Codex release as the managed runtime, remove obsolete 0.145.0 platform artifacts and unused semver compatibility, and preserve the latest main dependency upgrades.

Co-authored-by: Steven Lee <stevenlee@openai.com>

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 06:21:25 -04:00
Vincent Koc
951e7a39bd fix(protocol): make Swift model checks non-mutating (#115793)
* fix(protocol): make Swift drift checks non-mutating

* test(protocol): cover core Swift gateway frames

* docs(protocol): clarify Swift model update flow
2026-07-29 18:17:36 +08:00
maweibin
aa4c9416a7 docs(status): document missing --timeout flag (#102363) 2026-07-29 05:59:18 -04:00
Peter Steinberger
f318df7a55 refactor(ui): dissolve the General settings page into Appearance (#115798)
* refactor(ui): dissolve the General settings page into Appearance

* test(ui): drop dissolved config route expectation

* test(ui): cover legacy General model redirect

* style(ui): format legacy redirect test
2026-07-29 05:49:20 -04:00
Peter Steinberger
bde6b166c0 refactor(channels): deduplicate ingress monitor shells (#115792)
* refactor(channels): deduplicate ingress monitor shells

* fix(channels): preserve ingress error overload types

* fix(channels): type ingress error overload implementation

* chore(plugin-sdk): ratchet ingress error surface
2026-07-29 05:33:00 -04:00
Hannes Rudolph
6dc55fa65e fix(plugins): recover user turns with scoped reply hooks (#114836)
Allow before_agent_reply plugins to declare host-enforced trigger eligibility so scheduled-only hooks do not block interrupted user-turn recovery. Keep omitted and malformed scopes fail-closed, scope both memory-core maintenance hooks, and cover three runner reload cycles through the public registration contract.

Refs: #111442

Source: #114836

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 17:22:16 +08:00
Peter Steinberger
e8524a5839 feat: add Fish Audio S2.1 and local MLX speech (#115790)
* feat: add Fish Audio speech support

* chore: remove unused speech exports

* chore: keep Fish API constant private

* test: remove stale code mode import

* style: use bracket access for Fish voice ids

* test: restore QA evidence validator import
2026-07-29 05:15:33 -04:00
Peter Steinberger
994ca7d259 fix(msteams): honor group and channel conversation allowlists (#115746)
* fix(msteams): honor group conversation allowlists

Fixes #95737. Preserve opaque Teams conversation identities, the documented group fallback, personal-DM isolation, and display-name spoof protection.

Based on the original contributor fix in #95764.

Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>

* test(msteams): isolate conversation allowlist regression proof

Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>

---------

Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>
2026-07-29 05:05:42 -04:00