Skip to content

Add "verbose limit" support for configuring exec tool display truncat…#55770

Open
hiqiuyi wants to merge 3 commits into
openclaw:mainfrom
hiqiuyi:main
Open

Add "verbose limit" support for configuring exec tool display truncat…#55770
hiqiuyi wants to merge 3 commits into
openclaw:mainfrom
hiqiuyi:main

Conversation

@hiqiuyi

@hiqiuyi hiqiuyi commented Mar 27, 2026

Copy link
Copy Markdown

● Summary

  • Problem: Verbose mode always truncated exec tool command display at a hard-coded 120 chars with no way to change it
    per session.
  • Why it matters: Users running long commands (e.g. complex shell pipelines) couldn't see enough of the command in
    tool logs to understand what was executed.
  • What changed: Added /verbose limit command across TUI, web UI, and messaging (Telegram) surfaces. The limit is
    stored in the session entry (verboseLimit), persisted via sessions.patch, and threaded to compactRawCommand() through
    resolveToolDisplay → resolveExecDetail. A single DEFAULT_VERBOSE_LIMIT = 120 constant replaces the previous inline
    magic number.
  • What did NOT change: Default truncation behavior (120 chars) is unchanged when verboseLimit is not set. Verbose
    on/off/full logic is untouched.

Change Type

  • Feature
  • Refactor required for the fix

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • API / contracts
  • UI / DX

Linked Issue/PR

N/A

Root Cause / Regression History

N/A

Regression Test Plan

N/A — new feature, no prior behavior to regress.

  • If no new test is added, why not: the feature is a display-only formatting parameter with no side effects on agent
    behavior or data integrity.

User-visible / Behavior Changes

  • New command: /verbose limit (integer ≥ 1) — sets max display length for exec tool command logs in verbose mode.
  • /verbose limit (no arg) — shows the current limit.
  • Default remains 120 chars when unset.
  • Setting persists across sessions (stored in session entry).

Diagram

Before:
/verbose on → exec tool log always truncated at 120 chars

After:
/verbose limit 300 → stored in session
exec tool log → compactRawCommand(cmd, 300) → truncated at 300 chars

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No — uses existing sessions.patch RPC
  • Command/tool execution surface changed? No — display-only
  • Data access scope changed? No

Repro + Verification

Steps

  1. Start a session with /verbose on
  2. Run a long exec command — confirm truncation at 120 chars (default)
  3. Send /verbose limit 300
  4. Run the same long exec command — confirm truncation at 300 chars
  5. Restart/reload session — confirm limit persists

Expected

  • Step 4: command display extended to 300 chars
  • Step 5: verboseLimit: 300 survives session reload

Human Verification

  • Verified via Telegram: /verbose limit 1000 correctly stored and applied to exec tool display
  • Verified directive parser now captures numeric suffix (/verbose limit 50 → rawVerboseLevel = "limit 50")
  • Web UI and TUI paths verified in prior conversation turns
  • Not verified: cron-isolated-agent path (uses same AgentRunContext registry, should work)

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: verboseLimit not populated in AgentRunContext for runs registered before the session entry is resolved (e.g.
    gateway-side ACP runs).
    • Mitigation: The field is optional; missing it falls back to DEFAULT_VERBOSE_LIMIT = 120, preserving prior
      behavior.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: M labels Mar 27, 2026
@greptile-apps

greptile-apps Bot commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a /verbose limit <n> command across TUI, web UI, and Telegram surfaces to let users configure the maximum display length of exec tool command logs in verbose mode. The implementation is thorough: DEFAULT_VERBOSE_LIMIT = 120 replaces the hard-coded inline value, verboseLimit is persisted in the session entry, threaded through AgentRunContext, and propagated through the entire resolveToolDisplay → resolveExecDetail → compactRawCommand call chain for all three surfaces.

Key findings:

  • Stale verboseLimit in TUI on session switchloadHistory uses record.verboseLimit ?? state.sessionInfo.verboseLimit, so if the loaded session has no saved limit the previous session's value is kept, and chatLog.setVerboseLimit is called with the stale number. Tool cards rendered after the switch will truncate at the wrong length.
  • applySessionInfo never clears chatLog limit — the if (entry?.verboseLimit !== undefined) guard means chatLog.setVerboseLimit is never called with undefined, so receiving a session entry without a limit (e.g. after a null patch) leaves the ChatLog in the wrong state.
  • The web UI path (activeSession?.verboseLimit) is not affected by either issue — it reads directly from the session row on every render.
  • Minor: compactRawCommand(unwrapped, maxLength ?? DEFAULT_VERBOSE_LIMIT) is slightly redundant since compactRawCommand already defaults to DEFAULT_VERBOSE_LIMIT.

Confidence Score: 4/5

Safe to merge after fixing the two TUI stale-state issues; web UI and backend paths are correct.

Two P1 defects in the TUI path: (1) loadHistory falls back to the previous session's verboseLimit on switch, causing the wrong truncation length for the newly loaded session; (2) applySessionInfo's conditional guard means chatLog is never reset when a session entry lacks a verboseLimit. Both produce incorrect display state. The rest of the implementation — directive parsing, gateway schema, sessions-patch, web UI, and backend threading — is solid.

src/tui/tui-session-actions.ts — both the loadHistory (line 310) and applySessionInfo (line 180) verboseLimit update paths need attention.

Important Files Changed

Filename Overview
src/tui/tui-session-actions.ts Two stale-state issues: loadHistory falls back to the previous session's verboseLimit on switch, and applySessionInfo never calls setVerboseLimit(undefined) to clear the chatLog limit when an entry lacks the field.
src/agents/tool-display-exec.ts Extracts DEFAULT_VERBOSE_LIMIT = 120 constant and threads optional maxLength through resolveExecDetail → compactRawCommand; logic is correct with one minor redundancy in the ?? fallback.
src/auto-reply/reply/directives.ts Correctly extends matchLevelDirective/extractLevelDirective to optionally consume a numeric suffix (e.g. 'limit 50') for specified keyword levels.
src/auto-reply/reply/directive-handling.impl.ts Handles 'limit [n]' branch cleanly; integer validation (Number.isInteger + n >= 1) is correct, and session store update pattern matches existing code.
src/gateway/sessions-patch.ts verboseLimit patch handling (set / null-clear) is consistent with the pattern used for every other optional session field.
ui/src/ui/views/chat.ts Passes activeSession?.verboseLimit as execDetailMaxLength directly from the session row, so the web UI correctly resets to undefined on session switch (no stale-state issue).
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/tui/tui-session-actions.ts
Line: 310-311

Comment:
**Stale `verboseLimit` on session switch**

When a user switches to a session that has no saved `verboseLimit`, `record.verboseLimit` is `undefined`. The `?? state.sessionInfo.verboseLimit` fallback then preserves the *previous* session's limit, so `chatLog.setVerboseLimit` is called with a stale value. Every exec tool card shown in the new session will use the wrong truncation length.

The same session-switch fallback pattern is used for `verboseLevel` / `thinkingLevel` / etc. on the lines above and is a pre-existing quirk, but those fields don't feed `chatLog` state; `verboseLimit` does, making this observable.

Because `loadHistory` is the "cold" session-load path (full reload, `chatLog.clearAll()` follows immediately), the right behaviour here is to take whatever the server returned — `undefined` meaning "use the default":

```suggestion
      state.sessionInfo.verboseLimit = record.verboseLimit;
      chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/tui/tui-session-actions.ts
Line: 180-183

Comment:
**`chatLog` limit not reset when entry clears `verboseLimit`**

`applySessionInfo` is also called by the live-session-update path (e.g. after a session reload or when the gateway pushes a new entry). If the incoming `entry` doesn't carry `verboseLimit` (e.g. because it was null-patched to remove the limit), the `if` guard means `chatLog.setVerboseLimit` is never called with `undefined`, so the chatLog silently retains the previously-applied limit for all future tool cards.

The same concern applies if the user ever sets `verboseLimit: null` via `sessions.patch``applySessionInfo` would receive an entry with `verboseLimit === undefined` and leave chatLog unchanged.

Consider calling `setVerboseLimit` unconditionally so the chatLog always reflects the resolved session state:

```suggestion
    next.verboseLimit = entry?.verboseLimit;
    chatLog.setVerboseLimit(next.verboseLimit);
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/tool-display-exec.ts
Line: 418

Comment:
**Redundant default in `compactRawCommand` call**

`compactRawCommand` already declares `maxLength = DEFAULT_VERBOSE_LIMIT` as a default parameter, so passing `maxLength ?? DEFAULT_VERBOSE_LIMIT` is redundant — when `maxLength` is `undefined` both expressions produce the same result. Simplifying removes the need to keep two places in sync if the default ever changes:

```suggestion
  const compact = compactRawCommand(unwrapped, maxLength);
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Add "verbose limit" support for configur..." | Re-trigger Greptile

Comment on lines +310 to +311
state.sessionInfo.verboseLimit = record.verboseLimit ?? state.sessionInfo.verboseLimit;
chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);

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 Stale verboseLimit on session switch

When a user switches to a session that has no saved verboseLimit, record.verboseLimit is undefined. The ?? state.sessionInfo.verboseLimit fallback then preserves the previous session's limit, so chatLog.setVerboseLimit is called with a stale value. Every exec tool card shown in the new session will use the wrong truncation length.

The same session-switch fallback pattern is used for verboseLevel / thinkingLevel / etc. on the lines above and is a pre-existing quirk, but those fields don't feed chatLog state; verboseLimit does, making this observable.

Because loadHistory is the "cold" session-load path (full reload, chatLog.clearAll() follows immediately), the right behaviour here is to take whatever the server returned — undefined meaning "use the default":

Suggested change
state.sessionInfo.verboseLimit = record.verboseLimit ?? state.sessionInfo.verboseLimit;
chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);
state.sessionInfo.verboseLimit = record.verboseLimit;
chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tui/tui-session-actions.ts
Line: 310-311

Comment:
**Stale `verboseLimit` on session switch**

When a user switches to a session that has no saved `verboseLimit`, `record.verboseLimit` is `undefined`. The `?? state.sessionInfo.verboseLimit` fallback then preserves the *previous* session's limit, so `chatLog.setVerboseLimit` is called with a stale value. Every exec tool card shown in the new session will use the wrong truncation length.

The same session-switch fallback pattern is used for `verboseLevel` / `thinkingLevel` / etc. on the lines above and is a pre-existing quirk, but those fields don't feed `chatLog` state; `verboseLimit` does, making this observable.

Because `loadHistory` is the "cold" session-load path (full reload, `chatLog.clearAll()` follows immediately), the right behaviour here is to take whatever the server returned — `undefined` meaning "use the default":

```suggestion
      state.sessionInfo.verboseLimit = record.verboseLimit;
      chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +180 to +183
if (entry?.verboseLimit !== undefined) {
next.verboseLimit = entry.verboseLimit;
chatLog.setVerboseLimit(entry.verboseLimit);
}

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 chatLog limit not reset when entry clears verboseLimit

applySessionInfo is also called by the live-session-update path (e.g. after a session reload or when the gateway pushes a new entry). If the incoming entry doesn't carry verboseLimit (e.g. because it was null-patched to remove the limit), the if guard means chatLog.setVerboseLimit is never called with undefined, so the chatLog silently retains the previously-applied limit for all future tool cards.

The same concern applies if the user ever sets verboseLimit: null via sessions.patchapplySessionInfo would receive an entry with verboseLimit === undefined and leave chatLog unchanged.

Consider calling setVerboseLimit unconditionally so the chatLog always reflects the resolved session state:

Suggested change
if (entry?.verboseLimit !== undefined) {
next.verboseLimit = entry.verboseLimit;
chatLog.setVerboseLimit(entry.verboseLimit);
}
next.verboseLimit = entry?.verboseLimit;
chatLog.setVerboseLimit(next.verboseLimit);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tui/tui-session-actions.ts
Line: 180-183

Comment:
**`chatLog` limit not reset when entry clears `verboseLimit`**

`applySessionInfo` is also called by the live-session-update path (e.g. after a session reload or when the gateway pushes a new entry). If the incoming `entry` doesn't carry `verboseLimit` (e.g. because it was null-patched to remove the limit), the `if` guard means `chatLog.setVerboseLimit` is never called with `undefined`, so the chatLog silently retains the previously-applied limit for all future tool cards.

The same concern applies if the user ever sets `verboseLimit: null` via `sessions.patch``applySessionInfo` would receive an entry with `verboseLimit === undefined` and leave chatLog unchanged.

Consider calling `setVerboseLimit` unconditionally so the chatLog always reflects the resolved session state:

```suggestion
    next.verboseLimit = entry?.verboseLimit;
    chatLog.setVerboseLimit(next.verboseLimit);
```

How can I resolve this? If you propose a fix, please make it concise.

const cwd = cwdRaw?.trim() || result?.chdirPath || undefined;

const compact = compactRawCommand(unwrapped);
const compact = compactRawCommand(unwrapped, maxLength ?? DEFAULT_VERBOSE_LIMIT);

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 Redundant default in compactRawCommand call

compactRawCommand already declares maxLength = DEFAULT_VERBOSE_LIMIT as a default parameter, so passing maxLength ?? DEFAULT_VERBOSE_LIMIT is redundant — when maxLength is undefined both expressions produce the same result. Simplifying removes the need to keep two places in sync if the default ever changes:

Suggested change
const compact = compactRawCommand(unwrapped, maxLength ?? DEFAULT_VERBOSE_LIMIT);
const compact = compactRawCommand(unwrapped, maxLength);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tool-display-exec.ts
Line: 418

Comment:
**Redundant default in `compactRawCommand` call**

`compactRawCommand` already declares `maxLength = DEFAULT_VERBOSE_LIMIT` as a default parameter, so passing `maxLength ?? DEFAULT_VERBOSE_LIMIT` is redundant — when `maxLength` is `undefined` both expressions produce the same result. Simplifying removes the need to keep two places in sync if the default ever changes:

```suggestion
  const compact = compactRawCommand(unwrapped, maxLength);
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

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: 0a40672f2a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +269 to +270
await client.request("sessions.patch", { key: sessionKey, verboseLimit: n });
return { content: `Verbose limit set to **${n}**.` };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Trigger refresh after applying /verbose limit

executeVerbose patches verboseLimit but returns only content, while dispatchSlashCommand only reloads sessions/history when result.action === "refresh" (ui/src/ui/app-chat.ts). As a result, the active session snapshot keeps the old verboseLimit, so tool cards continue truncating exec commands at the previous length until a manual refresh or navigation occurs.

Useful? React with 👍 / 👎.

Comment on lines +310 to +311
state.sessionInfo.verboseLimit = record.verboseLimit ?? state.sessionInfo.verboseLimit;
chatLog.setVerboseLimit(state.sessionInfo.verboseLimit);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear stale verboseLimit when history omits it

When loading a different session, this assignment keeps the prior session’s verboseLimit whenever the new session has no override (undefined). That leaks truncation settings across sessions (e.g., session A set to 500, session B unset still renders at 500), which breaks per-session behavior and makes TUI tool display inconsistent with stored session state.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

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: ae2bd61f1b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +180 to +183
if (entry?.verboseLimit !== undefined) {
next.verboseLimit = entry.verboseLimit;
chatLog.setVerboseLimit(entry.verboseLimit);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset verboseLimit when session entry omits override

This update only applies verboseLimit when the field is present, so a previously set limit is never cleared on refresh paths that return verboseLimit as undefined (for example after sessions.patch clears it with null, or when a session has no override). In that case state.sessionInfo.verboseLimit and tool rendering keep using the stale old value, so truncation no longer matches persisted session state.

Useful? React with 👍 / 👎.

@hiqiuyi

hiqiuyi commented Mar 27, 2026

Copy link
Copy Markdown
Author

What could be causing this? It works fine locally when I run pnpm check and pnpm build.

@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep open: the requested configurable verbose exec-display limit is not on current main, but this branch still has source-proven blockers around current exec detail options, stale session state, Web refresh, invalid argument parsing, and missing real behavior proof.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

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

Yes for the review blockers from source: the PR's Web /verbose limit path patches the session without returning action: "refresh", and the TUI paths retain previous values when verboseLimit is absent. I did not run a live repro because this cleanup review is read-only.

Is this the best way to solve the issue?

No: the configurable limit is a plausible feature, but this branch is not the best merge shape until it is rebased onto the current display/session APIs, fixes stale state, and supplies real behavior proof.

Security review:

Security review cleared: No dependency, workflow, secret, permission, or supply-chain change was found; the concrete concerns are functional session-state and compatibility risks covered separately.

AGENTS.md: found and applied where relevant.

What I checked:

  • stale F-rated PR: PR was opened 2026-03-27T12:14:43Z, is older than 30 days, and the latest review rated it F.
  • proof blocker: real behavior proof is missing and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • Vincent Koc: Blame on current compactRawCommand, tool display common, TUI session actions, and gateway session schema points to the recent mainline refresh commit, and a later Control UI lazy-loading commit touched the chat surface. (role: recent area contributor; confidence: medium; commits: bad449301ffc, b3c946999d71; files: src/agents/tool-display-exec.ts, src/agents/tool-display-common.ts, src/tui/tui-session-actions.ts)
  • Peter Steinberger: Git history shows earlier commits splitting exec tool display parsing and building the verbose/session directive machinery that this PR extends. (role: feature-history owner; confidence: high; commits: ca0159569954, 99dd4288622a, 097550c29930; files: src/agents/tool-display-exec.ts, src/agents/tool-display-common.ts, src/auto-reply/reply/directive-handling.impl.ts)
  • Jacob Tomlinson: Recent merged work tightened persisted verbose defaults and authorization in the same directive/session persistence path. (role: adjacent owner; confidence: medium; commits: c6031235288a; files: src/auto-reply/reply/directive-handling.impl.ts, src/auto-reply/reply/directive-handling.persist.ts, src/gateway/server.chat.gateway-server-chat.test.ts)
  • Val Alexander: Git history shows the Control UI chat slash-command executor was introduced in the dashboard-v2 chat infrastructure work, which this PR modifies for /verbose limit. (role: adjacent Control UI contributor; confidence: medium; commits: c5ea6134d041; files: ui/src/ui/chat/slash-command-executor.ts)

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

@clawsweeper clawsweeper Bot added the mantis: telegram-visible-proof Mantis should capture Telegram visible proof. label May 11, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 11, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 19, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui gateway Gateway runtime mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant