Skip to content

fix: add clear separator between metadata and user message#41299

Closed
puppylpg wants to merge 1 commit into
openclaw:mainfrom
puppylpg:fix/add-user-message-separator
Closed

fix: add clear separator between metadata and user message#41299
puppylpg wants to merge 1 commit into
openclaw:mainfrom
puppylpg:fix/add-user-message-separator

Conversation

@puppylpg

@puppylpg puppylpg commented Mar 9, 2026

Copy link
Copy Markdown

Summary

  • Problem: When a user message is passed to the LLM, the metadata blocks (sender info, conversation info, etc.) and the actual user message content are joined with only double newlines. This causes the LLM to sometimes misinterpret the message structure, treating the metadata as the entire message and ignoring the actual user content ("message is empty" replies).
  • Why it matters: Users intermittently get incorrect "message is empty" responses even though their message was correctly stored in session history.
  • What changed:
    • runtime-context-prompt.ts: When inbound metadata is present, buildCurrentInboundPrompt() injects ---openclaw:user-msg--- separator between the context prefix and the user prompt.
    • strip-inbound-meta.ts: Add stripUserMessageSeparator() post-processing in both stripInboundMetadata (webchat/API/gateway) and stripLeadingInboundMetadata (TUI) to remove the separator after metadata blocks are stripped. Gated on didStripMetadata flag for defense-in-depth.
    • strip-inbound-meta.test.ts: 7 new tests covering separator stripping and legacy preservation.
  • What did NOT change (scope boundary): No API changes, no new types, no changes to buildInboundUserContextPrefix, no metadata format changes.

Why ---openclaw:user-msg--- instead of ---\n**User Message:**

The separator is a program-generated marker that cannot exist in any legacy stored message or user-typed content. This eliminates the need for complex detection logic (_sep markers, seenUserContent flags, structural JSON parsing) and makes legacy message compatibility trivial: the stripper only removes ---openclaw:user-msg---, which legacy data never contains.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • None

User-visible / Behavior Changes

  • LLM now receives a clear ---openclaw:user-msg--- separator between metadata and user content, reducing "message is empty" false positives.
  • The separator is stripped in all user-facing surfaces (TUI, webchat, gateway API, session cost logs).
  • Legacy messages (pre-upgrade) are completely unaffected — the unique marker cannot appear in historical data.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux (Ubuntu 24.04)
  • Runtime: Node v24.15.0, pnpm 10.23.0

Steps

  1. Send a message to the LLM through any channel with metadata (group chat, sender info, etc.)
  2. Observe the prompt construction in buildCurrentInboundPrompt()
  3. Verify the separator appears between metadata and user content
  4. Verify stripInboundMetadata / stripLeadingInboundMetadata removes the separator in user-facing views

Expected

  • LLM correctly distinguishes metadata from user message content
  • No separator visible in TUI/webchat/gateway/session logs

Actual

  • Confirmed working as expected in unit tests and live CLI verification (see Real behavior proof below)

Evidence

  • Passing tests: 39 strip-inbound-meta tests pass (7 new separator-specific tests)
  • New tests cover: separator after single/multiple metadata blocks, no-metadata preservation, non-separator --- preservation, sentinel-without-metadata-block edge case, legacy message preservation

Real behavior proof

Live CLI verification on the rebased branch (b69cb795):

Behavior or issue addressed: Metadata and user message content are joined with only double newlines, causing the LLM to misinterpret the message structure and ignore actual user content.

Real environment tested: Local OpenClaw development setup on Ubuntu 24.04 with Node v24.15.0.

Exact steps or command run after this patch:

  1. npx tsx proof-test.mjs - Live CLI verification of separator injection and stripping
  2. pnpm test strip-inbound-meta - Unit tests for the new separator logic

Evidence after fix:

=== Real Behavior Proof: User Message Separator ===

1. buildCurrentInboundPrompt WITH metadata:
---
Conversation info (untrusted metadata):
```json
{"channel": "#general", "sender": "Alice"}

---openclaw:user-msg---
Hello, how are you?

✅ Separator ---openclaw:user-msg--- is present between metadata and user message

  1. buildCurrentInboundPrompt WITHOUT metadata:

Hello, how are you?

✅ No separator injected when metadata is absent

  1. stripInboundMetadata (metadata + separator):
    Input: (metadata + separator + user message)
    Output: Hello, how are you?
    ✅ Metadata and separator both removed

  2. stripLeadingInboundMetadata (metadata + separator):
    Input: (metadata + separator + user message)
    Output: Hello, how are you?
    ✅ Metadata and separator both removed in leading-only strip mode

  3. Legacy message (no metadata, user has --- in content):
    Input: Hello\n\n---\nSome user markdown
    Output: Hello\n\n---\nSome user markdown (preserved intact)
    ✅ Legacy user content preserved, no false stripping

=== All checks passed ===


All tests (39 total) pass.

**Observed result after fix:** The separator is correctly injected when metadata is present and correctly stripped in all user-facing surfaces. Legacy messages without metadata are completely unaffected.

**What was not tested:** Live end-to-end with real LLM provider (simulated in unit tests).

## Human Verification (required)

- Verified scenarios: metadata with separator injection, separator stripping after single/multiple metadata blocks, preservation when no metadata present, preservation of `---` in non-separator context
- Edge cases checked: legacy messages with `---\n**User Message:**` user content (preserved intact), sentinel text without metadata fences, user content starting with generic `---`
- What you did **not** verify: Live end-to-end with real LLM provider

## Review Conversations

- [x] I replied to or resolved every bot review conversation I addressed in this PR.
- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.

## Compatibility / Migration

- Backward compatible? `Yes` — legacy messages are unaffected; the unique marker cannot appear in pre-upgrade data
- Config/env changes? `No`
- Migration needed? `No`

## Failure Recovery (if this breaks)

- How to disable/revert this change quickly: Revert the single commit
- Files/config to restore: `runtime-context-prompt.ts`, `strip-inbound-meta.ts`
- Known bad symptoms: `---openclaw:user-msg---` appearing in TUI/webchat/session history

## Risks and Mitigations

- Risk: LLM treats `---openclaw:user-msg---` as confusing noise
  - Mitigation: The marker reads like a boundary tag; LLMs routinely handle similar delimiters in system/user prompts. It's a single line and less disruptive than the metadata blocks themselves.

@greptile-apps

greptile-apps Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR addresses an LLM parsing issue by inserting an explicit ---\n**User Message:**\n separator between injected metadata blocks and the actual user message content in get-reply-run.ts. The motivation and the change in get-reply-run.ts are sound, but the stripping side has two issues that need attention.

Issues found:

  • Separator leaks through stripInboundMetadata (logic bug): stripLeadingInboundMetadata (TUI) is updated to remove the separator, but stripInboundMetadata — used in chat-sanitize.ts for webchat/API history and in session-cost-usage.ts — is not updated. Any message that passes through those code paths will surface the raw --- / **User Message:** text to end-users.

  • Unconditional --- stripping breaks old-format messages (logic bug): In stripLeadingInboundMetadata, --- is consumed before confirming that **User Message:** follows. For messages persisted before this PR whose actual body begins with a Markdown horizontal rule (---), that leading line will be silently dropped from the displayed text.

Confidence Score: 2/5

  • Not safe to merge — the separator will leak as visible text in webchat and API responses via stripInboundMetadata.
  • The root cause fix is valid, but the stripping logic is incomplete: stripInboundMetadata (used by chat-sanitize.ts and session-cost-usage.ts) does not remove the new separator, so it will appear verbatim in user-facing chat history. Additionally, the unconditional --- stripping in stripLeadingInboundMetadata can silently corrupt legacy messages.
  • Focus on src/auto-reply/reply/strip-inbound-meta.ts — both the stripInboundMetadata function (separator not stripped) and the backwards-compatibility of the new --- guard in stripLeadingInboundMetadata.

Last reviewed commit: c2cd9f0

Comment thread src/auto-reply/reply/strip-inbound-meta.ts Outdated
Comment thread src/auto-reply/reply/strip-inbound-meta.ts Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2cd9f06ab

ℹ️ 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 thread src/auto-reply/reply/get-reply-run.ts Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0ab9b0a9e

ℹ️ 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 thread src/auto-reply/reply/strip-inbound-meta.ts Outdated
@puppylpg
puppylpg force-pushed the fix/add-user-message-separator branch from 8f97557 to 4f98411 Compare March 10, 2026 00:07
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling channel: googlechat Channel integration: googlechat extensions: memory-core Extension: memory-core labels Mar 10, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f502cb1b9a

ℹ️ 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 thread src/auto-reply/reply/strip-inbound-meta.ts Outdated
@puppylpg
puppylpg force-pushed the fix/add-user-message-separator branch from 5b49e83 to 8487e81 Compare March 10, 2026 02:52
@openclaw-barnacle openclaw-barnacle Bot removed the extensions: memory-core Extension: memory-core label Mar 10, 2026
@puppylpg
puppylpg force-pushed the fix/add-user-message-separator branch from 8487e81 to 4f98411 Compare March 10, 2026 02:54
@openclaw-barnacle openclaw-barnacle Bot removed channel: googlechat Channel integration: googlechat agents Agent runtime and tooling labels Mar 10, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad61ebd9e5

ℹ️ 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 thread src/auto-reply/reply/strip-inbound-meta.ts Outdated
Comment thread src/auto-reply/reply/strip-inbound-meta.ts Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f24d4eda1

ℹ️ 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 thread src/auto-reply/reply/inbound-meta.ts Outdated

@puppylpg puppylpg left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

All review comments have been addressed:

  1. ✅ Separator now stripped by both stripInboundMetadata and stripLeadingInboundMetadata
  2. ✅ Only strip separator when full pattern --- + **User Message:** is present
  3. ✅ Skip leading blank lines before checking separator
  4. ✅ Only strip separator when metadata was actually removed (strippedMetadata flag)
  5. ✅ Added _sep: true marker to distinguish new format from legacy
  6. ✅ Only add _sep marker when conversation info has actual fields

Thanks for the thorough review!

@puppylpg
puppylpg force-pushed the fix/add-user-message-separator branch from a7fe27e to 7f6bc91 Compare March 10, 2026 15:36

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f6bc918d2

ℹ️ 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 thread src/auto-reply/reply/get-reply-run.ts Outdated
@@ -303,7 +303,9 @@ export async function runPreparedReply(
);
const baseBodyForPrompt = isBareSessionReset
? baseBodyFinal
: [inboundUserContext, baseBodyFinal].filter(Boolean).join("\n\n");
: inboundUserContext
? `${inboundUserContext}\n\n---\n**User Message:**\n${baseBodyFinal}`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Gate separator injection on marker-capable metadata

The new ---\n**User Message:** wrapper is added whenever inboundUserContext is non-empty, but both sanitizers only remove that wrapper when they detect "_sep" inside stripped metadata. buildInboundUserContextPrefix can still emit metadata without a conversation block (for example sender-only direct contexts), so those messages get the separator injected but never stripped in TUI/web/gateway/session views, leaving user-visible ---/**User Message:** prefixes. Please only inject the wrapper when the emitted metadata includes the marker, or make separator stripping independent of the conversation block marker.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in commit 2a5ea09 (fix: gate separator injection on hasSeparatorMarker flag). The separator is now only injected when inboundUserContextResult.hasSeparatorMarker is true. The hasSeparatorMarker flag is set for both conversation info blocks and sender info blocks, ensuring consistent injection/stripping for all metadata types.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3366efbb11

ℹ️ 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 +164 to +165
if (line.includes('"_sep"')) {
hasNewFormatMarker = true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Parse _sep marker structurally before stripping separator

The new marker detection uses a raw substring check (line.includes('"_sep"')) inside any stripped JSON block, so legacy metadata can be misclassified as “new format” when user-controlled fields contain that text (for example a quoted/replied body value like _sep). In that case, if the real user message begins with the two-line pattern --- + **User Message:**, both sanitizers will now strip those legitimate leading lines even though no formatter-injected separator was present. Please parse the metadata JSON and require a top-level _sep: true marker instead of matching arbitrary JSON text.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in commit 1af618e (fix: parse _sep marker structurally before stripping separator). The detection now uses JSON.parse() to parse the metadata block, then checks "_sep" in parsed using the in operator. This prevents false positives from user-controlled fields that happen to contain the text _sep.

@puppylpg

Copy link
Copy Markdown
Author

Good catch! I've updated the marker detection to parse JSON structurally instead of using raw substring checks.

Now both stripInboundMetadata and stripLeadingInboundMetadata:

  1. Collect the JSON lines during parsing
  2. Parse the JSON structurally with JSON.parse()
  3. Check for _sep field using the in operator: "_sep" in parsed

This prevents false positives when user-controlled fields (like quoted message bodies) happen to contain the text "_sep".

Commit: a36dd9b

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a36dd9b67a

ℹ️ 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".

// Only strip the separator if we actually stripped metadata AND the metadata
// contains the new format marker (_sep). This prevents corrupting legacy user
// content that happens to start with the separator pattern.
if (strippedMetadata && hasNewFormatMarker) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Restrict separator stripping to leading metadata blocks

stripInboundMetadata now removes the leading --- + **User Message:** pair whenever any stripped block contains _sep, but this check does not verify that the stripped metadata was actually a leading OpenClaw prefix. In the gateway/web/session sanitization paths that call this function, a user message that intentionally starts with those two lines can lose them if the same message later includes a quoted metadata block (for example copied logs containing _sep). This is new content corruption introduced by the separator-removal pass; gate separator removal on stripping metadata from the start of the message.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in commit 137ddca (fix: restrict separator stripping to leading metadata blocks only). The seenUserContent flag ensures that only metadata at the start of the message (before any user content) can trigger separator removal. A metadata block appearing later in the text (e.g., quoted logs) is ignored for separator-stripping purposes.

@puppylpg

Copy link
Copy Markdown
Author

You're right, this was a bug. Fixed in commit f7a0336.

Now stripInboundMetadata only strips the separator when the metadata with _sep was stripped from the start of the message, not from the middle.

Added a seenUserContent flag to track whether we've output any non-metadata content yet. Only leading metadata (before any user content) can trigger separator stripping.

This prevents corrupting user content that:

  1. Starts with the separator pattern (--- + **User Message:**)
  2. Contains a quoted metadata block with _sep in the middle

@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Jun 8, 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. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 8, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 9, 2026
@puppylpg

puppylpg commented Jun 9, 2026

Copy link
Copy Markdown
Author

Rebased onto latest main and updated PR description with real behavior proof. All tests passing (39/39). Ready for review.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels Jun 13, 2026
@clawsweeper clawsweeper Bot added mantis: telegram-visible-proof Mantis should capture Telegram visible proof. and removed mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels Jun 20, 2026
@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared June 20, 2026 13:37 Inactive
@clawsweeper clawsweeper Bot added the mantis: telegram-visible-proof Mantis should capture Telegram visible proof. label Jun 20, 2026
@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared June 20, 2026 14:42 Inactive
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. label Jun 25, 2026
@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

  • Action: closed this PR.
  • Close reason: duplicate or superseded.
  • Evidence: durable ClawSweeper review.
  • Coverage proof: PR B clearly carries PR A's core useful intent with the safer canonical implementation path identified by the durable report; PR A's delimiter-specific code and tests are incidental to a superseded approach and do not need independent review. Covering PR: fix: carry reply metadata into runtime context #90745.

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

Labels

agents Agent runtime and tooling 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: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. 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: S 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. triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant