refactor: reuse shared coercion helpers#86419
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed May 25, 2026, 3:51 PM ET / 19:51 UTC. Summary Reproducibility: not applicable. as an issue reproduction; this is a PR review. The blocking concerns are source-reproducible from the diff: public SDK export expansion, Google Meet record coercion broadening, memory extraPaths stringification, and locale-dependent shared sorting. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance: Risk before merge
Maintainer options:
Next step before merge Security Review findings
Review detailsBest possible solution: Land only a narrowed refactor that preserves existing coercion semantics, keeps public SDK exports intentional and documented, uses deterministic sorting, and includes redacted real behavior proof. Do we have a high-confidence way to reproduce the issue? Not applicable as an issue reproduction; this is a PR review. The blocking concerns are source-reproducible from the diff: public SDK export expansion, Google Meet record coercion broadening, memory extraPaths stringification, and locale-dependent shared sorting. Is this the best way to solve the issue? No; the cleanup direction is reasonable, but the current implementation broadens public API and config/path semantics. The safer solution is a narrower refactor that preserves existing behavior and adds real runtime proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against a0023fbfa0ab. Label changesLabel changes:
Label justifications:
Evidence reviewedSecurity concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
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 PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
Verification for head Behavior addressed: PR branch rebased onto current
|
Summary
uniqueStrings, unique normalized entries, and unique trimmed-list variants.Verification
git diff --checknode scripts/run-tsgo.mjs -p tsconfig.json --noEmit --pretty falsepnpm test src/shared/string-normalization.test.ts src/infra/path-env.test.ts src/infra/path-prepend.test.ts src/gateway/node-command-policy.test.ts src/infra/outbound/outbound-policy.test.ts src/plugins/provider-validation.test.ts src/plugins/bundle-manifest.test.ts src/model-catalog/provider-index/normalize.test.ts src/commands/doctor/shared/allowfrom-fallback-migration.test.ts src/commands/doctor/shared/allowlist-policy-repair.test.ts src/plugins/setup-registry.test.ts src/plugins/plugin-registry.test.ts src/plugins/registry.runtime-config.test.ts src/channels/plugins/catalog.test.ts src/channels/message/receipt.test.ts src/hooks/gmail.test.ts src/proxy-capture/store.sqlite.test.ts src/auto-reply/commands-registry.test.ts src/auto-reply/model.test.ts src/config/channel-capabilities.test.ts src/infra/exec-safe-bin-trust.test.tspnpm test ui/src/ui/chat/slash-commands.browser-import.test.ts src/auto-reply/commands-registry.test.tspnpm test src/hooks/workspace.test.ts src/hooks/install.test.ts src/plugin-sdk/channel-streaming.test.ts src/agents/codex-native-web-search.test.ts src/media-understanding/runner.video.test.ts src/media-understanding/media-understanding-misc.test.ts src/agents/tool-policy.test.ts src/agents/sandbox/tool-policy.test.ts src/agents/sandbox/registry.test.ts src/agents/tool-catalog.test.ts src/agents/tool-allowlist-guard.test.tspnpm test src/infra/update-runner.test.ts src/agents/auth-profiles/persisted-boundary.test.ts src/channels/message-access/message-access.test.ts src/auto-reply/skill-commands.test.ts src/plugin-sdk/access-groups.test.ts src/plugin-sdk/ssrf-policy.test.ts src/agents/pi-embedded-subscribe.tools.extract.test.ts src/agents/pi-embedded-subscribe.tools.media.test.ts src/agents/pi-embedded-subscribe.handlers.messages.test.ts src/agents/pi-embedded-runner/run/tool-media-payloads.test.ts src/agents/subagent-target-policy.test.ts src/agents/skills/filter.test.ts src/media/local-roots.test.ts src/agents/tools/media-tool-shared.test.ts src/commands/onboarding-plugin-install.test.ts src/infra/exec-safe-bin-trust.test.tspnpm test src/cli/channel-options.test.ts src/pairing/allow-from-store-file.test.ts src/agents/harness/runtime-plugin.test.ts src/infra/command-analysis/risks.test.ts src/infra/command-analysis/inline-eval.test.ts src/infra/command-analysis/explain.test.ts src/infra/command-analysis/explain.lazy.test.tspnpm test src/infra/host-env-security.test.ts src/infra/exec-safe-bin-trust.test.ts src/infra/approval-native-route-notice.test.ts src/gateway/protocol/index.test.ts src/gateway/server-plugins.test.ts src/gateway/session-transcript-files.fs.archive-events.test.ts src/gateway/session-utils.test.ts src/utils/message-channel.test.ts src/agents/memory-search.test.ts src/agents/auth-profiles/persisted-boundary.test.ts src/agents/cli-backends.test.ts src/agents/cli-runner/prepare.test.ts src/agents/model-scan.test.ts src/agents/openclaw-tools.media-factory-plan.test.ts src/agents/pi-embedded-subscribe.handlers.messages.test.ts src/agents/pi-tools.policy.test.ts src/agents/tools/message-tool.test.ts src/gateway/server/ws-connection/message-handler.post-connect-health.test.tspnpm test src/commands/auth-choice-options.test.ts src/commands/doctor-memory-search.test.ts src/commands/onboard-helpers.test.ts src/commands/migrate/selection.test.ts src/commands/models/list.provider-catalog.test.ts src/commands/doctor/shared/context-engine-host-compat.test.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts src/commands/doctor/shared/plugin-dependency-cleanup.test.ts src/talk/session-log-runtime.test.tspnpm test packages/memory-host-sdk/src/host/internal.test.ts packages/memory-host-sdk/src/host/backend-config.test.tspnpm test src/shared/string-normalization.test.ts extensions/phone-control/index.test.ts extensions/slack/src/scopes.test.ts extensions/xai/src/responses-tool-shared.test.ts extensions/discord/src/components.test.ts extensions/discord/src/send.components.test.ts extensions/anthropic/stream-wrappers.test.ts extensions/msteams/src/attachments/graph.test.ts extensions/irc/src/setup.test.tspnpm test src/secrets/provider-env-vars.test.ts src/secrets/provider-env-vars.dynamic.test.ts src/secrets/channel-env-vars.dynamic.test.ts src/secrets/runtime.test.ts src/secrets/runtime.fast-path.test.ts src/secrets/runtime-web-tools.test.ts src/secrets/runtime-command-secrets.test.ts src/secrets/resolve.test.ts src/channels/plugins/account-helpers.test.ts src/channels/plugins/message-actions.test.ts src/plugins/activation-planner.test.ts src/plugins/tools.optional.test.ts src/plugins/provider-runtime.test.ts src/plugins/discovery.test.ts src/commands/onboard-auth.test.tspnpm test src/video-generation/runtime.test.ts src/video-generation/capabilities.test.ts src/media-understanding/defaults.test.ts src/media-understanding/runner.video.test.ts src/media-understanding/media-understanding-misc.test.ts src/media-understanding/runner.cli-audio.test.ts src/daemon/service-env.test.ts src/daemon/service-audit.test.ts src/daemon/schtasks.test.ts src/cli/devices-cli.test.ts src/cli/plugins-authoring-command.test.ts src/cron/run-log.test.ts src/agents/model-auth.test.ts src/agents/models-config.providers.live-filter.test.ts src/plugins/captured-registration.test.ts src/infra/command-analysis/explain.test.ts src/plugins/plugin-registry.test.tspnpm test src/shared/string-normalization.test.tspnpm test src/plugin-sdk/session-transcript-hit.test.ts src/plugin-sdk/channel-policy.test.ts src/cli/daemon-cli/status.gather.test.ts src/agents/tool-search.test.ts src/agents/code-mode.test.ts src/agents/model-auth-markers.test.ts src/agents/openai-reasoning-effort.test.ts src/plugins/provider-self-hosted-setup.test.ts src/plugins/registry.provider-like.test.ts src/agents/subagent-registry-lifecycle.test.ts src/infra/provider-usage.auth.normalizes-keys.test.tspnpm test src/channels/status/read-model.test.ts src/channels/config-presence.test.ts src/channels/plugins/read-only.test.ts src/cli/command-secret-targets.test.ts src/cli/command-secret-targets.import.test.ts src/cli/config-cli.test.ts src/cron/isolated-agent/delivery-target.test.ts src/tasks/task-registry.test.ts src/plugins/document-extractors.runtime.test.ts src/plugins/plugin-registry.test.ts src/config/doc-baseline.test.ts src/config/io.shell-env-expected-keys.test.ts src/cli/run-main.exit.test.tspnpm test extensions/whatsapp/src/inbound/send-result.test.ts extensions/whatsapp/src/inbound/extract.test.ts extensions/whatsapp/src/inbound.test.ts extensions/moonshot/src/kimi-web-search-provider.test.ts extensions/perplexity/src/perplexity-web-search-provider.test.ts extensions/google-meet/index.test.ts extensions/google-meet/src/transports/chrome.test.ts extensions/telegram/src/status.test.ts extensions/nostr/src/channel.inbound.test.tspnpm test src/infra/bonjour-discovery.test.ts src/infra/tailnet.test.ts src/infra/npm-install-env.test.ts src/auto-reply/heartbeat-filter.test.ts src/flows/doctor-repair-flow.test.ts src/commands/model-picker.test.ts src/plugins/provider-model-helpers.test.ts src/agents/openai-transport-stream.test.ts src/agents/pi-embedded-runner/tool-name-allowlist.test.ts src/gateway/server-methods/agent.test.ts src/gateway/server-methods/chat.directive-tags.test.tspnpm test extensions/qa-lab/src/token-efficiency-report.test.ts extensions/qa-lab/src/cli.runtime.test.ts extensions/qa-lab/src/character-eval.test.ts extensions/qa-lab/src/scenario-packs.test.ts extensions/qa-lab/src/qa-gateway-config.test.ts extensions/qa-lab/src/multipass.runtime.test.ts extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.test.ts extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.test.ts extensions/qa-lab/src/live-transports/slack/slack-live.runtime.test.ts extensions/qa-lab/src/live-transports/discord/discord-live.runtime.test.ts extensions/qa-matrix/src/substrate/config.test.ts extensions/qa-matrix/src/substrate/client.test.tspnpm test extensions/memory-core/src/dreaming-phases.test.ts extensions/memory-core/src/dreaming.test.ts extensions/memory-core/src/short-term-promotion.test.ts extensions/memory-core/src/memory/manager-search.test.ts extensions/memory-core/src/memory/search-manager.test.ts extensions/memory-core/src/memory/qmd-manager.test.ts extensions/memory-wiki/src/query.test.ts extensions/memory-wiki/src/compile.test.ts extensions/memory-wiki/src/cli.test.tspnpm test extensions/mattermost/src/mattermost/monitor-auth.test.ts extensions/mattermost/src/mattermost/monitor.test.ts extensions/msteams/src/polls.test.ts extensions/discord/src/monitor/thread-bindings.lifecycle.test.ts extensions/discord/src/voice/command.test.ts extensions/feishu/src/bot.broadcast.test.ts extensions/telegram/src/message-dispatch-dedupe.test.ts extensions/telegram/src/state-migrations.test.ts extensions/matrix/src/matrix/sdk.test.ts extensions/matrix/src/matrix/actions/polls.test.ts extensions/matrix/src/matrix/monitor/events.test.ts extensions/imessage/src/monitor/inbound-processing.test.ts extensions/ollama/src/provider-models.test.ts extensions/browser/src/browser/routes/permissions.test.ts extensions/browser/src/browser/chrome-mcp.test.tspnpm test extensions/qqbot/src/engine/gateway/interaction-handler.test.ts extensions/qqbot/src/engine/gateway/stages/envelope-stage.test.ts extensions/qqbot/src/engine/commands/builtin/log-helpers.test.ts extensions/codex/src/migration/provider.test.ts extensions/codex/src/app-server/models.test.ts extensions/migrate-hermes/config.test.ts extensions/policy/src/doctor/register.test.ts extensions/volcengine/index.test.tspnpm test src/infra/outbound/session-binding-service.test.ts src/infra/exec-safe-bin-trust.test.ts src/config/redact-snapshot.raw.test.ts src/auto-reply/reply/startup-context.test.ts src/security/audit-extra.async.test.ts src/agents/harness/native-hook-relay.test.tspnpm test src/agents/openclaw-tools.session-status.test.ts src/agents/pi-hooks/compaction-safeguard.test.ts src/security/audit-channel-source-config-slack.test.ts src/security/audit-channel-source-config-discord.test.ts src/security/audit-channel-dm-policy.test.ts src/security/audit-channel-readonly-setup-fallback.test.ts src/security/audit-channel-readonly-resolution.test.ts src/security/audit-channel-account-metadata.test.tspnpm test extensions/comfy/index.test.ts extensions/comfy/image-generation-provider.test.ts extensions/comfy/video-generation-provider.test.ts extensions/comfy/music-generation-provider.test.tspnpm test src/plugins/hooks.sync-only.test.ts src/plugins/hooks.before-tool-call.test.ts src/plugins/plugin-registry.test.ts src/test-utils/openclaw-test-state.test.ts src/agents/tools/message-tool.test.ts src/agents/pi-tools.policy.test.ts src/plugins/provider-public-artifacts.test.ts src/plugins/document-extractor-public-artifacts.test.ts src/plugins/web-provider-public-artifacts.test.tspnpm test extensions/memory-core/src/memory/manager-search.test.ts extensions/memory-core/src/memory/search-manager.test.ts extensions/memory-core/src/memory/qmd-manager.test.ts extensions/qa-matrix/src/substrate/client.test.ts extensions/openai/openai-codex-provider.test.ts src/shared/string-normalization.test.ts src/plugin-sdk/channel-policy.test.tspnpm test src/infra/restart-stale-pids.test.ts src/infra/gateway-processes.test.ts extensions/matrix/src/matrix/actions/polls.test.ts extensions/browser/src/browser/chrome-mcp.test.ts extensions/browser/src/browser/pw-session.page-cdp.test.ts src/gateway/mcp-http.test.ts src/agents/pi-tools.schema.test.ts src/agents/pi-tools.policy.test.ts src/agents/schema/clean-for-gemini.test.tspnpm test src/channels/bundled-channel-catalog-read.test.ts src/channels/plugins/catalog.test.ts src/plugins/official-external-plugin-catalog.test.ts src/plugins/manifest-registry.test.ts src/config/validation.channel-metadata.test.ts src/auto-reply/reply/group-id.test.ts src/infra/outbound/outbound-session.test.ts src/media-understanding/runner.video.test.ts src/media-understanding/media-understanding-misc.test.ts src/media/image-ops.helpers.test.ts src/media/web-media.test.ts src/plugins/bundled-plugin-metadata.test.ts src/plugins/stage-bundled-plugin-runtime.test.ts src/plugins/public-surface-loader.test.ts src/cli/gateway-cli/qa-parent-watchdog.test.ts src/commands/doctor-state-integrity.test.ts extensions/meeting-notes/index.test.ts extensions/memory-core/src/dreaming-phases.test.ts extensions/memory-wiki/src/apply.test.ts extensions/memory-wiki/src/cli.test.ts extensions/active-memory/index.test.ts extensions/feishu/src/docx.test.ts extensions/qa-lab/src/gateway-child.test.ts extensions/qa-lab/src/run-config.test.tspnpm test src/plugin-sdk/reply-payload.test.ts src/plugin-sdk/provider-entry.test.ts src/plugin-sdk/windows-spawn.test.ts src/plugin-sdk/allow-from.test.ts src/agents/channel-tools.test.ts src/agents/memory-search.test.ts src/agents/openai-reasoning-effort.test.ts src/agents/models-config.providers.live-filter.test.ts src/agents/models-config.providers.implicit.discovery-scope.test.ts src/agents/live-auth-keys.test.ts src/agents/model-scan.test.ts src/agents/tool-search.test.ts src/agents/cli-output.test.ts src/agents/system-prompt-params.test.ts src/agents/pi-embedded-runner/run/attempt.session-lock.test.ts src/agents/pi-embedded-runner/run/attempt.tool-call-normalization.test.ts src/agents/pi-embedded-runner/run.incomplete-turn.test.ts src/agents/bash-tools.exec-runtime.test.ts src/agents/bash-tools.exec-approval-request.test.ts src/agents/skills-install.test.ts src/agents/skills-install-fallback.test.tspnpm test src/channels/account-snapshot-fields.test.ts src/channels/plugins/setup-group-access.test.ts src/channels/plugins/setup-group-access-configure.test.ts src/channels/plugins/setup-wizard-helpers.test.ts src/channels/message-access/message-access.test.ts src/plugins/setup-registry.test.ts src/plugins/setup-registry.runtime.test.ts src/plugins/captured-registration.test.ts src/plugins/plugin-scope.test.ts src/plugins/dependency-denylist.test.ts src/plugins/document-extractors.runtime.test.ts src/plugins/config-contracts.test.ts src/agents/model-compat.test.tspnpm test packages/memory-host-sdk/src/host/internal.test.ts packages/memory-host-sdk/src/host/backend-config.test.ts src/media-understanding/runner.video.test.ts src/media-understanding/media-understanding-misc.test.ts src/media-understanding/runner.cli-audio.test.ts src/cron/run-log.test.ts src/secrets/runtime-config-collectors-plugins.bundled.test.tspnpm test extensions/voice-call/src/webhook.test.ts extensions/voice-call/src/webhook-security.test.ts extensions/voice-call/src/response-generator.test.ts extensions/twitch/src/setup-surface.test.ts extensions/twitch/src/outbound.test.ts extensions/tlon/src/core.test.ts extensions/zalouser/src/setup-surface.test.ts extensions/line/src/reply-payload-transform.test.ts extensions/line/src/setup-surface.test.ts extensions/telegram/src/bot-handlers.runtime.test.tspnpm test extensions/slack/src/interactive-replies.test.ts extensions/irc/src/setup.test.ts extensions/msteams/src/sdk.test.ts extensions/msteams/src/outbound.test.ts extensions/msteams/src/probe.test.ts extensions/msteams/src/directory-live.test.ts extensions/msteams/src/polls.test.ts extensions/meeting-notes/index.test.ts extensions/meeting-notes/src/cli.test.tspnpm test extensions/memory-core/src/memory/hybrid.test.ts extensions/memory-core/src/memory/manager-search.test.ts extensions/memory-core/src/memory/search-manager.test.ts extensions/memory-core/src/dreaming-phases.test.ts extensions/memory-core/src/dreaming.test.ts extensions/memory-core/src/dreaming-repair.test.tspnpm test extensions/openai/embedding-batch.test.ts extensions/google/embedding-provider.test.ts extensions/anthropic/stream-wrappers.test.ts extensions/lmstudio/src/setup.test.tspnpm test extensions/qa-lab/src/coverage-report.test.ts extensions/qa-lab/src/docker-up.runtime.test.ts extensions/qa-lab/src/docker-harness.test.ts extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.test.ts extensions/qa-matrix/src/substrate/client.test.ts extensions/qa-matrix/src/substrate/config.test.tspnpm test src/commands/docs.test.ts src/infra/gateway-process-argv.test.ts src/infra/ssh-tunnel.test.ts src/infra/install-source-utils.test.ts src/daemon/systemd-unit.test.ts src/daemon/systemd.test.ts src/daemon/service-audit.test.tspnpm test extensions/feishu/src/outbound.test.ts extensions/feishu/src/comment-shared.test.ts extensions/synology-chat/src/core.test.ts extensions/synology-chat/src/channel.test.ts extensions/nostr/src/channel.test.ts extensions/whatsapp/src/resolve-outbound-target.test.ts extensions/whatsapp/src/auto-reply/monitor/inbound-dispatch.test.ts extensions/imessage/src/actions.runtime.test.ts extensions/imessage/src/probe.test.tspnpm test src/infra/bonjour-discovery.test.ts src/infra/exec-approval-forwarder.test.ts src/infra/clawhub.test.ts src/infra/control-ui-assets.test.ts src/infra/update-runner.test.ts src/security/audit-extra.async.test.ts src/security/audit-gateway.test.ts src/gateway/server-methods/config.test.ts src/wizard/setup.plugin-config.test.ts src/gateway/server-methods/agent.test.ts src/cli/plugins-install-config.test.tspnpm test extensions/slack/src/scopes.test.ts extensions/slack/src/setup-surface.test.ts extensions/phone-control/index.test.ts extensions/qa-matrix/src/substrate/config.test.ts extensions/telegram/src/message-dispatch-dedupe.test.ts extensions/telegram/index.test.ts extensions/discord/index.test.ts extensions/lmstudio/src/setup.test.ts extensions/memory-wiki/src/apply.test.ts extensions/memory-wiki/src/cli.test.ts extensions/zalouser/src/setup-surface.test.tspnpm test src/security/audit-gateway.test.ts src/plugin-sdk/channel-policy.test.ts extensions/browser/src/node-host/invoke-browser.test.ts extensions/signal/src/normalize.test.ts extensions/mattermost/src/mattermost/monitor-onchar.test.ts extensions/msteams/src/channel.test.ts extensions/matrix/src/matrix/sdk.test.ts extensions/memory-core/src/short-term-promotion.test.ts extensions/qa-lab/src/suite.test.tspnpm test ui/src/ui/chat/message-extract.test.ts ui/src/ui/views/agents-panels-tools-skills.browser.test.ts ui/src/ui/views/cron.test.ts ui/src/ui/app-render.helpers.browser.test.ts extensions/qa-matrix/src/runners/contract/runtime.test.ts extensions/codex/src/app-server/event-projector.test.ts extensions/memory-core/src/dreaming-phases.test.ts extensions/acpx/src/runtime.test.ts extensions/whatsapp/src/inbound/send-result.test.ts extensions/active-memory/index.test.ts extensions/matrix/src/approval-handler.runtime.test.ts extensions/mattermost/src/mattermost/monitor-resources.test.ts src/auto-reply/commands-registry.test.ts src/commands/agent.runtime-config.test.tspnpm test extensions/qa-lab/src/character-eval.test.ts extensions/qa-lab/src/gateway-child.test.ts src/agents/subagent-announce-delivery.test.ts src/agents/subagent-announce.test.tspnpm test src/agents/model-auth.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/channels/plugins/account-helpers.test.ts src/infra/net/ssrf.test.ts src/media-understanding/apply.test.ts extensions/whatsapp/src/inbound.test.tspnpm test extensions/irc/src/normalize.test.ts extensions/irc/src/setup.test.ts src/agents/auth-health.test.ts src/agents/subagent-target-policy.test.ts src/infra/net/ssrf.test.ts src/model-catalog/manifest-planner.test.ts src/plugins/tools.optional.test.ts src/security/audit-extra.sync.test.tspnpm test src/agents/model-auth.test.ts src/plugin-sdk/ssrf-policy.test.ts src/agents/tool-allowlist-guard.test.ts src/agents/pi-embedded-runner/run/attempt-tool-construction-plan.test.ts src/pairing/allow-from-store-read.test.ts src/security/audit-extra.async.test.ts src/infra/provider-usage.auth.plugin.test.ts src/infra/provider-usage.auth.normalizes-keys.test.ts src/plugins/web-provider-public-artifacts.test.ts src/plugins/web-provider-public-artifacts.fallback.test.tspnpm test src/auto-reply/reply/commands-dock.test.ts src/commands/doctor-command-owner.test.ts src/gateway/server-methods/nodes-pending.test.ts src/gateway/server-methods/nodes.invoke-wake.test.ts src/agents/tools/sessions-resolution.test.ts src/agents/skills.test.ts src/agents/skills.buildworkspaceskillsnapshot.test.ts src/agents/auth-profiles/state-observation.test.tspnpm test src/shared/string-coerce.test.ts src/commands/doctor-session-state-providers.test.ts src/commands/sandbox-explain.test.ts src/agents/runtime-capabilities.test.ts src/agents/system-prompt.test.ts extensions/matrix/src/matrix/monitor/auto-join.test.ts extensions/matrix/src/approval-handler.runtime.test.ts extensions/qqbot/src/command-auth.test.ts extensions/signal/src/monitor/access-policy.test.ts ui/src/ui/controllers/cron.test.ts ui/src/ui/views/activity.test.tspnpm test extensions/discord/src/monitor/native-command.plugin-dispatch.test.ts extensions/slack/src/monitor/slash.test.ts extensions/synology-chat/src/channel.test.tspnpm test src/shared/string-normalization.test.ts src/infra/host-env-security.test.ts src/infra/host-env-security.policy-parity.test.ts src/infra/host-env-security.reported-baseline.test.ts src/gateway/node-catalog.test.ts src/gateway/server-methods/environments.test.ts src/plugins/providers.test.ts src/plugins/contracts/loader.contract.test.ts src/plugins/contracts/registry.contract.test.ts extensions/qa-lab/src/providers/image-generation.test.ts extensions/slack/src/channel.test.ts extensions/slack/src/interactive-replies.test.tspnpm test src/commands/doctor-device-pairing.test.ts extensions/slack/src/monitor/events/interactions.test.tspnpm test extensions/lmstudio/src/models.test.ts src/agents/api-key-rotation.test.ts src/agents/model-auth-label.test.ts src/agents/harness/runtime-plugin.test.ts src/channels/channel-config.test.ts src/gateway/input-allowlist.test.tspnpm test src/commands/doctor-device-pairing.test.ts src/media-generation/catalog.test.ts src/channels/plugins/directory-config-helpers.test.tspnpm test src/shared/string-normalization.test.ts src/infra/diagnostic-flags.test.ts src/agents/pi-tools.policy.test.ts src/channels/plugins/session-conversation.test.ts src/channels/plugins/session-conversation.bundled-fallback.test.ts extensions/tlon/src/monitor/settings-helpers.test.ts extensions/tlon/src/core.test.tspnpm test src/agents/bootstrap-budget.test.ts src/agents/pi-auth-discovery.external-cli.test.ts src/gateway/sessions-patch.test.ts src/agents/subagent-spawn.depth-limits.test.ts src/agents/tools/sessions-spawn-tool.test.ts src/infra/device-pairing.test.ts src/infra/device-pairing-churn.test.ts extensions/codex/src/app-server/config.test.ts src/agents/subagent-announce-delivery.test.ts src/agents/tools/media-generate-background-shared.test.tspnpm test extensions/codex/src/commands.test.ts extensions/codex/src/app-server/config.test.tsenv -u OPENCLAW_TESTBOX pnpm check:changed/Users/steipete/Projects/agent-skills/skills/autoreview/scripts/autoreview --mode localReal behavior proof
Behavior addressed: Repeated string-list normalization code is centralized without changing trim, blank-drop, ordering, sorting, or dedupe semantics at the touched call sites; string-only raw-array normalization still skips non-strings; the browser command registry import boundary remains unchanged.
Real environment tested: Local macOS checkout on repo Node/pnpm defaults.
Exact steps or command run after this patch:
git diff --check;node scripts/run-tsgo.mjs -p tsconfig.json --noEmit --pretty false; targetedpnpm testcommands listed above;env -u OPENCLAW_TESTBOX pnpm check:changed;/Users/steipete/Projects/agent-skills/skills/autoreview/scripts/autoreview --mode local.Evidence after fix: Earlier targeted tests passed 21 files / 252 tests across 8 Vitest shards; browser-import follow-up passed 2 files / 30 tests across 2 shards; trimmed-list/tool-policy batch passed 11 files / 127 tests across 5 shards; string-dedupe helper batch passed 16 files / 276 tests across 7 shards; local dedupe helper batch passed 7 files / 57 tests across 5 shards; latest internal string dedupe batch passed 18 files / 508 tests across 5 shards; command/talk string dedupe batch passed 9 files / 161 tests across 3 shards plus the rerun of plugin-tool warnings passed 1 file / 30 tests; memory SDK path dedupe batch passed 2 files / 31 tests; plugin SDK/export batch passed 9 files / 107 tests across 7 shards plus the IRC rerun passed 1 file / 10 tests; core secrets/channel/plugin helper batch passed 15 files / 342 tests across 4 shards; shared unique-value helper batch passed 17 files / 365 tests across 7 shards plus the helper unit rerun passed 1 file / 33 tests; agent utility unique-helper batch passed 10 files / 185 tests across 5 shards after dropping one nonexistent direct test path; config/channel unique-helper batch passed 13 files / 405 tests across 7 shards after dropping one nonexistent direct test path; extension unique-helper batch passed 9 files / 201 tests across 6 shards; core utility unique-helper batch passed 11 files / 530 tests across 6 shards; QA Lab/Matrix unique-helper batch passed 12 files / 234 tests across 2 shards; memory plugin unique-helper batch passed 9 files / 355 tests across 1 shard; channel plugin unique-helper batch passed 15 files / 325 tests across 9 shards; plugin-tail unique-helper batch passed 8 files / 199 tests across 3 shards; core-tail unique-helper batch passed 14 files / 258 tests across 8 shards after dropping three nonexistent direct paths; Comfy workflow unique-helper batch passed 4 files / 17 tests across 1 shard; core test-helper unique-helper batch passed 9 files / 181 tests across 3 shards; plugin unique-values export batch passed 7 files / 247 tests across 4 shards; numeric/schema unique-helper batch passed 9 files / 249 tests with 2 skipped across 6 shards; index-filter dedupe batch passed 24 files across 14 shards; agent/plugin-sdk trim-normalization batch passed 21 files / 393 tests across 3 shards; channel/plugin helper trim-normalization batch passed 13 files / 221 tests across 4 shards; memory/media/secrets trim-normalization batch passed 7 files / 65 tests across 4 shards; extension trim-normalization batch passed 10 files / 168 tests across 5 shards; channel parser trim-normalization batch passed 9 files / 82 tests across 4 shards; memory search trim-normalization batch passed 6 files / 149 tests across 1 shard; provider parser trim-normalization batch passed 4 files / 61 tests across 2 shards after dropping one nonexistent Voyage direct test path; QA runtime trim-normalization batch passed 6 files / 44 tests across 2 shards after dropping one nonexistent docker-runtime direct test path; infra parser trim-normalization batch passed 7 files / 140 tests across 4 shards; messaging parser trim-normalization batch passed 9 files / 240 tests across 4 shards; core parser trim-normalization batch passed 11 files / 290 tests across 5 shards; extension parser trim-normalization batch passed 11 files / 96 tests across 8 shards; remaining parser trim-normalization batch passed 9 files / 198 tests across 8 shards; final parser trim-normalization batch passed 14 files / 377 tests across 10 shards; QA media normalization batch passed 4 files / 143 tests across 2 shards; provider/media normalization batch passed 6 files / 208 tests across 5 shards; set-filter normalization batch passed 8 files / 161 tests across 4 shards; policy allowlist normalization batch passed 10 files / 169 tests across 5 shards; session/owner normalization batch passed 8 files / 75 tests across 4 shards; primitive string-list helper batch passed 11 files / 179 tests across 7 shards; lowercase entry helper batch passed 3 files / 89 tests across 3 shards; sorted helper batch passed 12 files / 210 tests across 7 shards; unique trimmed helper batch passed 2 files / 51 tests across 2 shards; final helper reuse batch passed 6 files / 69 tests across 4 shards; catalog helper reuse batch passed 3 files / 22 tests across 2 shards; remaining string helper batch passed 7 files / 144 tests across 4 shards; final list-normalization batch passed 10 files / 279 tests across 5 shards; Codex auth order helper batch passed 2 files / 159 tests across 1 shard; root tsgo passed; extension tsgo rerun passed after removing an unused import;
check:changedpassed typecheck, lint, import-cycle, and guard lanes; autoreview reported no accepted/actionable findings.Observed result after fix: PR diff is now 725 files, +2511/-3730, net -1219 LOC, while replacing another obvious string/list normalization and dedupe cluster with shared helpers.
What was not tested: Live provider and cross-platform E2E scenarios; this is a local refactor.
pnpm buildwas not rerun after the final helper batches.