Wire diagnostics through the core chat command (#72936)

* feat: wire codex diagnostics feedback

* fix: harden codex diagnostics hints

* fix: neutralize codex diagnostics output

* fix: tighten codex diagnostics safeguards

* fix: bound codex diagnostics feedback output

* fix: tighten codex diagnostics throttling

* fix: confirm codex diagnostics uploads

* docs: clarify codex diagnostics add-on

* fix: route diagnostics through core command

* fix: tighten diagnostics authorization

* fix: pin diagnostics to bundled codex command

* fix: limit owner status in plugin commands

* fix: scope diagnostics confirmations

* fix: scope codex diagnostics cooldowns

* fix: harden codex diagnostics ownership scopes

* fix: harden diagnostics command trust and display

* fix: keep diagnostics command trust internal

* fix: clarify diagnostics exec boundary

* fix: consume codex diagnostics confirmations atomically

* test: include codex diagnostics binding metadata

* test: use string codex binding timestamps

* fix: keep reserved command trust host-only

* fix: harden diagnostics trust and resume hints

* wire diagnostics through exec approval

* fix: keep diagnostics tests aligned with bundled root trust

* fix telegram diagnostics owner auth

* route trajectory exports through exec approval

* fix trajectory exec command encoding

* fix telegram group owner auth

* fix export trajectory approval hardening

* fix pairing command owner bootstrap

* fix telegram owner exec approvals

* fix: make diagnostics approval flow pasteable

* fix: route native sensitive command followups

* fix: invoke diagnostics exports with current cli

* fix: refresh exec approval protocol models

* fix: list codex diagnostics from thread bindings

* fix: fold codex diagnostics into exec approval

* fix: preserve diagnostics approval line breaks

* docs: clarify diagnostics codex workflow
This commit is contained in:
pashpashpash
2026-04-28 15:40:37 -07:00
committed by GitHub
parent 7e41913a20
commit 6ce1058296
78 changed files with 5727 additions and 315 deletions

View File

@@ -7,7 +7,7 @@ read_when:
title: "Pairing"
---
“Pairing” is OpenClaws explicit **owner approval** step.
“Pairing” is OpenClaws explicit access approval step.
It is used in two places:
1. **DM pairing** (who is allowed to talk to the bot)
@@ -34,6 +34,12 @@ openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
```
If no command owner is configured yet, approving a DM pairing code also bootstraps
`commands.ownerAllowFrom` to the approved sender, such as `telegram:123456789`.
That gives first-time setups an explicit owner for privileged commands and exec
approval prompts. After an owner exists, later pairing approvals only grant DM
access; they do not add more owners.
Supported channels: `bluebubbles`, `discord`, `feishu`, `googlechat`, `imessage`, `irc`, `line`, `matrix`, `mattermost`, `msteams`, `nextcloud-talk`, `nostr`, `openclaw-weixin`, `signal`, `slack`, `synology-chat`, `telegram`, `twitch`, `whatsapp`, `zalo`, `zalouser`.
### Where the state lives
@@ -53,7 +59,12 @@ Account scoping behavior:
Treat these as sensitive (they gate access to your assistant).
<Note>
This store is for DM access. Group authorization is separate. Approving a DM pairing code does not automatically allow that sender to run group commands or control the bot in groups. For group access, configure the channel's explicit group allowlists (for example `groupAllowFrom`, `groups`, or per-group or per-topic overrides depending on the channel).
The pairing allowlist store is for DM access. Group authorization is separate.
Approving a DM pairing code does not automatically allow that sender to run group
commands or control the bot in groups. First-owner bootstrap is separate config
state in `commands.ownerAllowFrom`, and group chat delivery still follows the
channel's group allowlists (for example `groupAllowFrom`, `groups`, or per-group
or per-topic overrides depending on the channel).
</Note>
## 2) Node device pairing (iOS/Android/macOS/headless nodes)

View File

@@ -122,8 +122,9 @@ Token resolution order is account-aware. In practice, config values win over env
For one-owner bots, prefer `dmPolicy: "allowlist"` with explicit numeric `allowFrom` IDs to keep access policy durable in config (instead of depending on previous pairing approvals).
Common confusion: DM pairing approval does not mean "this sender is authorized everywhere".
Pairing grants DM access only. Group sender authorization still comes from explicit config allowlists.
If you want "I am authorized once and both DMs and group commands work", put your numeric Telegram user ID in `channels.telegram.allowFrom`.
Pairing grants DM access. If no command owner exists yet, the first approved pairing also sets `commands.ownerAllowFrom` so owner-only commands and exec approvals have an explicit operator account.
Group sender authorization still comes from explicit config allowlists.
If you want "I am authorized once and both DMs and group commands work", put your numeric Telegram user ID in `channels.telegram.allowFrom`; for owner-only commands, make sure `commands.ownerAllowFrom` contains `telegram:<your user id>`.
### Finding your Telegram user ID
@@ -777,7 +778,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
Config path:
- `channels.telegram.execApprovals.enabled` (auto-enables when at least one approver is resolvable)
- `channels.telegram.execApprovals.approvers` (falls back to numeric owner IDs from `allowFrom` / `defaultTo`)
- `channels.telegram.execApprovals.approvers` (falls back to numeric owner IDs from `commands.ownerAllowFrom`, `allowFrom`, or `defaultTo`)
- `channels.telegram.execApprovals.target`: `dm` (default) | `channel` | `both`
- `agentFilter`, `sessionFilter`

View File

@@ -51,6 +51,7 @@ Notes:
- Doctor auto-migrates legacy flat Talk config (`talk.voiceId`, `talk.modelId`, and friends) into `talk.provider` + `talk.providers.<provider>`.
- Repeat `doctor --fix` runs no longer report/apply Talk normalization when the only difference is object key order.
- Doctor includes a memory-search readiness check and can recommend `openclaw configure --section model` when embedding credentials are missing.
- Doctor warns when no command owner is configured. The command owner is the human operator account allowed to run owner-only commands and approve dangerous actions. DM pairing only lets someone talk to the bot; if you approved a sender before first-owner bootstrap existed, set `commands.ownerAllowFrom` explicitly.
- If sandbox mode is enabled but Docker is unavailable, doctor reports a high-signal warning with remediation (`install Docker` or `openclaw config set agents.defaults.sandbox.mode off`).
- If `gateway.auth.token`/`gateway.auth.password` are SecretRef-managed and unavailable in the current command path, doctor reports a read-only warning and does not write plaintext fallback credentials.
- If channel SecretRef inspection fails in a fix path, doctor continues and reports a warning instead of exiting early.

View File

@@ -57,12 +57,19 @@ Options:
- `--account <accountId>`: account id for multi-account channels
- `--notify`: send a confirmation back to the requester on the same channel
Owner bootstrap:
- If `commands.ownerAllowFrom` is empty when you approve a pairing code, OpenClaw also records the approved sender as the command owner, using a channel-scoped entry such as `telegram:123456789`.
- This only bootstraps the first owner. Later pairing approvals do not replace or expand `commands.ownerAllowFrom`.
- The command owner is the human operator account allowed to run owner-only commands and approve dangerous actions such as `/diagnostics`, `/export-trajectory`, `/config`, and exec approvals.
## Notes
- Channel input: pass it positionally (`pairing list telegram`) or with `--channel <channel>`.
- `pairing list` supports `--account <accountId>` for multi-account channels.
- `pairing approve` supports `--account <accountId>` and `--notify`.
- If only one pairing-capable channel is configured, `pairing approve <code>` is allowed.
- If you approved a sender before this bootstrap existed, run `openclaw doctor`; it warns when no command owner is configured and shows the `openclaw config set commands.ownerAllowFrom ...` command to fix it.
## Related

View File

@@ -26,6 +26,17 @@ Scope selection:
- `--all-agents`: aggregate all configured agent stores
- `--store <path>`: explicit store path (cannot be combined with `--agent` or `--all-agents`)
Export a trajectory bundle for a stored session:
```bash
openclaw sessions export-trajectory --session-key "agent:main:telegram:direct:123" --workspace .
openclaw sessions export-trajectory --session-key "agent:main:telegram:direct:123" --output bug-123 --json
```
This is the command path used by the `/export-trajectory` slash command after
the owner approves the exec request. The output directory is always resolved
inside `.openclaw/trajectory-exports/` under the selected workspace.
`openclaw sessions --all-agents` reads configured agent stores. Gateway and ACP
session discovery are broader: they also include disk-only stores found under
the default `agents/` root or a templated `session.store` root. Those

View File

@@ -7,9 +7,13 @@ read_when:
- Reviewing what diagnostics data is recorded or redacted
---
OpenClaw can create a local diagnostics zip that is safe to attach to bug
reports. It combines sanitized Gateway status, health, logs, config shape, and
recent payload-free stability events.
OpenClaw can create a local diagnostics zip for bug reports. It combines
sanitized Gateway status, health, logs, config shape, and recent payload-free
stability events.
Treat diagnostics bundles like secrets until you have reviewed them. They are
designed to omit or redact payloads and credentials, but they still summarize
local Gateway logs and host-level runtime state.
## Quick start
@@ -29,6 +33,45 @@ For automation:
openclaw gateway diagnostics export --json
```
## Chat command
Owners can use `/diagnostics [note]` in chat to request a local Gateway export.
Use this when the bug happened in a real conversation and you want one
copy-pasteable report for support:
1. Send `/diagnostics` in the conversation where you noticed the problem. Add a
short note if it helps, for example `/diagnostics bad tool choice`.
2. OpenClaw sends the diagnostics preamble and asks for one explicit exec
approval. The approval runs `openclaw gateway diagnostics export --json`.
Do not approve diagnostics through an allow-all rule.
3. After approval, OpenClaw replies with a pasteable report containing the local
bundle path, manifest summary, privacy notes, and relevant session ids.
In group chats, an owner can still run `/diagnostics`, but OpenClaw does not
post the diagnostic details back into the shared chat. It sends the preamble,
approval prompts, Gateway export result, and Codex session/thread breakdown to
the owner through the private approval route. The group only gets a short notice
that the diagnostics flow was sent privately. If OpenClaw cannot find a private
owner route, the command fails closed and asks the owner to run it from a DM.
When the active OpenClaw session is using the native OpenAI Codex harness,
the same exec approval also covers an OpenAI feedback upload for the Codex
runtime threads OpenClaw knows about. That upload is separate from the local
Gateway zip and appears only for Codex harness sessions. Before approval, the
prompt explains that approving diagnostics will also send Codex feedback, but it
does not list Codex session or thread ids. After approval, the chat reply lists
the channels, OpenClaw session ids, Codex thread ids, and local resume commands
for the threads that were sent to OpenAI servers. If you deny or ignore the
approval, OpenClaw does not run the export, does not send Codex feedback, and
does not print the Codex ids.
That makes the common Codex debugging loop short: notice the bad behavior in
Telegram, Discord, or another channel, run `/diagnostics`, approve once, share
the report with support, then run the printed `codex resume <thread-id>` command
locally if you want to inspect the native Codex thread yourself. See
[Codex harness](/plugins/codex-harness#inspect-a-codex-thread-from-the-cli) for
that inspection workflow.
## What the export contains
The zip includes:

View File

@@ -302,6 +302,8 @@ Agents should route user requests by intent, not by the word "Codex" alone:
| "Bind this chat to Codex" | `/codex bind` |
| "Resume Codex thread `<id>` here" | `/codex resume <id>` |
| "Show Codex threads" | `/codex threads` |
| "File a support report for a bad Codex run" | `/diagnostics [note]` |
| "Only send Codex feedback for this attached thread" | `/codex diagnostics [note]` |
| "Use Codex as the runtime for this agent" | config change to `agentRuntime.id` |
| "Use my ChatGPT/Codex subscription with normal OpenClaw" | `openai-codex/*` model refs |
| "Run Codex through ACP/acpx" | ACP `sessions_spawn({ runtime: "acp", ... })` |
@@ -750,17 +752,90 @@ Common forms:
- `/codex resume <thread-id>` attaches the current OpenClaw session to an existing Codex thread.
- `/codex compact` asks Codex app-server to compact the attached thread.
- `/codex review` starts Codex native review for the attached thread.
- `/codex diagnostics [note]` asks before sending Codex diagnostics feedback for the attached thread.
- `/codex computer-use status` checks the configured Computer Use plugin and MCP server.
- `/codex computer-use install` installs the configured Computer Use plugin and reloads MCP servers.
- `/codex account` shows account and rate-limit status.
- `/codex mcp` lists Codex app-server MCP server status.
- `/codex skills` lists Codex app-server skills.
### Common debugging workflow
When a Codex-backed agent does something surprising in Telegram, Discord, Slack,
or another channel, start with the conversation where the problem happened:
1. Run `/diagnostics bad tool choice after image upload` or another short note
that describes what you saw.
2. Approve the diagnostics request once. The approval creates the local Gateway
diagnostics zip and, because the session is using the Codex harness, also
sends the relevant Codex feedback bundle to OpenAI servers.
3. Copy the completed diagnostics reply into the bug report or support thread.
It includes the local bundle path, privacy summary, OpenClaw session ids,
Codex thread ids, and an `Inspect locally` line for each Codex thread.
4. If you want to debug the run yourself, run the printed `Inspect locally`
command in a terminal. It looks like `codex resume <thread-id>` and opens the
native Codex thread so you can inspect the conversation, continue it locally,
or ask Codex why it chose a particular tool or plan.
Use `/codex diagnostics [note]` only when you specifically want the Codex
feedback upload for the currently attached thread without the full OpenClaw
Gateway diagnostics bundle. For most support reports, `/diagnostics [note]` is
the better starting point because it ties the local Gateway state and Codex
thread ids together in one reply. See [Diagnostics export](/gateway/diagnostics)
for the full privacy model and group-chat behavior.
Core OpenClaw also exposes owner-only `/diagnostics [note]` as the general
Gateway diagnostics command. Its approval prompt shows the sensitive-data
preamble, links to [Diagnostics Export](/gateway/diagnostics), and requests
`openclaw gateway diagnostics export --json` through explicit exec approval
every time. Do not approve diagnostics with an allow-all rule. After approval,
OpenClaw sends a pasteable report with the local bundle path and manifest
summary. When the active OpenClaw session is using the Codex harness, that
same approval also authorizes sending the relevant Codex feedback bundles to
OpenAI servers. The approval prompt says that Codex feedback will be sent, but
it does not list Codex session or thread ids before approval.
If `/diagnostics` is invoked by an owner in a group chat, OpenClaw keeps the
shared channel clean: the group receives only a short notice, while the
diagnostics preamble, approval prompts, and Codex session/thread ids are sent to
the owner through the private approval route. If there is no private owner route,
OpenClaw refuses the group request and asks the owner to run it from a DM.
The approved Codex upload calls Codex app-server `feedback/upload` and asks
app-server to include logs for each listed thread and spawned Codex subthreads
when available. The upload goes through Codex's normal feedback path to OpenAI
servers; if Codex feedback is disabled in that app-server, the command returns
the app-server error. The completed diagnostics reply lists the channels,
OpenClaw session ids, Codex thread ids, and local `codex resume <thread-id>`
commands for the threads that were sent. If you deny or ignore the approval,
OpenClaw does not print those Codex ids. This upload does not replace the local
Gateway diagnostics export.
`/codex resume` writes the same sidecar binding file that the harness uses for
normal turns. On the next message, OpenClaw resumes that Codex thread, passes the
currently selected OpenClaw model into app-server, and keeps extended history
enabled.
### Inspect a Codex thread from the CLI
The fastest way to understand a bad Codex run is often to open the native Codex
thread directly:
```sh
codex resume <thread-id>
```
Use this when you notice a bug in a channel conversation and want to inspect the
problematic Codex session, continue it locally, or ask Codex why it made a
particular tool or reasoning choice. The easiest path is usually to run
`/diagnostics [note]` first: after you approve it, the completed report lists
each Codex thread and prints an `Inspect locally` command, for example
`codex resume <thread-id>`. You can copy that command directly into a terminal.
You can also get a thread id from `/codex binding` for the current chat or
`/codex threads [filter]` for recent Codex app-server threads, then run the same
`codex resume` command in your shell.
The command surface requires Codex app-server `0.125.0` or newer. Individual
control methods are reported as `unsupported by this Codex app-server` if a
future or custom app-server does not expose that JSON-RPC method.

View File

@@ -92,7 +92,7 @@ There are two related systems:
Enables `/restart` plus gateway restart tool actions.
</ParamField>
<ParamField path="commands.ownerAllowFrom" type="string[]">
Sets the explicit owner allowlist for owner-only command/tool surfaces. Separate from `commands.allowFrom`.
Sets the explicit owner allowlist for owner-only command/tool surfaces. This is the human operator account that can approve dangerous actions and run commands such as `/diagnostics`, `/export-trajectory`, and `/config`. It is separate from `commands.allowFrom` and from DM pairing access.
</ParamField>
<ParamField path="channels.<channel>.commands.enforceOwnerForCommands" type="boolean" default="false">
Per-channel: makes owner-only commands require **owner identity** to run on that surface. When `true`, the sender must either match a resolved owner candidate (for example an entry in `commands.ownerAllowFrom` or provider-native owner metadata) or hold internal `operator.admin` scope on an internal message channel. A wildcard entry in channel `allowFrom`, or an empty/unresolved owner-candidate list, is **not** sufficient — owner-only commands fail closed on that channel. Leave this off if you want owner-only commands gated only by `ownerAllowFrom` and the standard command allowlists.
@@ -129,7 +129,7 @@ Current source-of-truth:
- `/stop` aborts the current run.
- `/session idle <duration|off>` and `/session max-age <duration|off>` manage thread-binding expiry.
- `/export-session [path]` exports the current session to HTML. Alias: `/export`.
- `/export-trajectory [path]` exports a JSONL [trajectory bundle](/tools/trajectory) for the current session. Alias: `/trajectory`.
- `/export-trajectory [path]` asks for exec approval, then exports a JSONL [trajectory bundle](/tools/trajectory) for the current session. Use it when you need the prompt, tool, and transcript timeline for one OpenClaw session. In group chats, the approval prompt and export result go to the owner privately. Alias: `/trajectory`.
</Accordion>
<Accordion title="Model and run controls">
@@ -150,6 +150,7 @@ Current source-of-truth:
- `/commands` shows the generated command catalog.
- `/tools [compact|verbose]` shows what the current agent can use right now.
- `/status` shows execution/runtime status, including `Execution`/`Runtime` labels and provider usage/quota when available.
- `/diagnostics [note]` is the owner-only support-report flow for Gateway bugs and Codex harness runs. It asks for explicit exec approval every time before running `openclaw gateway diagnostics export --json`; do not approve diagnostics with an allow-all rule. After approval, it sends a pasteable report with the local bundle path, manifest summary, privacy notes, and relevant session ids. In group chats, the approval prompt and report go to the owner privately. When the active session uses the OpenAI Codex harness, the same approval also sends relevant Codex feedback to OpenAI servers and the completed reply lists the OpenClaw session ids, Codex thread ids, and `codex resume <thread-id>` commands. See [Diagnostics Export](/gateway/diagnostics).
- `/crestodian <request>` runs the Crestodian setup and repair helper from an owner DM.
- `/tasks` lists active/recent background tasks for the current session.
- `/context [list|detail|json]` explains how context is assembled.
@@ -221,7 +222,7 @@ Bundled plugins can add more slash commands. Current bundled commands in this re
- `/phone status|arm <camera|screen|writes|all> [duration]|disarm` temporarily arms high-risk phone node commands.
- `/voice status|list [limit]|set <voiceId|name>` manages Talk voice config. On Discord, the native command name is `/talkvoice`.
- `/card ...` sends LINE rich card presets. See [LINE](/channels/line).
- `/codex status|models|threads|resume|compact|review|account|mcp|skills` inspects and controls the bundled Codex app-server harness. See [Codex harness](/plugins/codex-harness).
- `/codex status|models|threads|resume|compact|review|diagnostics|account|mcp|skills` inspects and controls the bundled Codex app-server harness. See [Codex harness](/plugins/codex-harness).
- QQBot-only commands:
- `/bot-ping`
- `/bot-version`

View File

@@ -20,6 +20,13 @@ Use it when you need to answer questions like:
- Which model, plugins, skills, and runtime settings were active?
- What usage and prompt-cache metadata did the provider return?
If you are filing a broad support report for a live Gateway issue, start with
[`/diagnostics`](/gateway/diagnostics#chat-command). Diagnostics collects the
sanitized Gateway bundle and, for OpenAI Codex harness sessions, can also send
Codex feedback to OpenAI servers after approval. Use `/export-trajectory` when
you specifically need the detailed per-session prompt, tool, and transcript
timeline.
## Quick start
Send this in the active session:
@@ -49,6 +56,20 @@ You can choose a relative output directory name:
The custom path is resolved inside `.openclaw/trajectory-exports/`. Absolute
paths and `~` paths are rejected.
Trajectory bundles can contain prompts, model messages, tool schemas, tool
results, runtime events, and local paths. The chat slash command therefore runs
through exec approval every time. Approve the export once when you intend to
create the bundle; do not use allow-all. In group chats, OpenClaw sends the
approval prompt and export result to the owner privately instead of posting the
trajectory details back to the shared room.
For local inspection or support workflows, you can also run the approved command
path directly:
```bash
openclaw sessions export-trajectory --session-key "agent:main:telegram:direct:123" --workspace .
```
## Access
Trajectory export is an owner command. The sender must pass the normal command