fix(ci): require write+ for Mantis label-triggered proof runs#4
Merged
Conversation
handleScannedLink does not set self.step = .connect after scanning a QR code from the welcome step. The scanner sheet dismisses and the UI returns to the welcome screen instead of showing connection progress. The sibling handleScannedSetupCode path correctly advances the step; this aligns the QR scan path. Fixes openclaw#98297 Co-authored-by: Cursor <cursoragent@cursor.com>
…claw#96644) postJson reads the Anthropic OAuth token endpoint response body with an unbounded await response.text(). A compromised or hijacked OAuth endpoint can stream an arbitrarily large body and force the runtime to buffer the entire payload before parsing — an OOM/DoS vector. Replace with readResponseWithLimit at 16 MiB cap + TextDecoder decode to match the sibling bounded-read pattern (provider-http-errors.ts:308). Co-authored-by: Claude <noreply@anthropic.com>
* fix(gateway): warn for blocked configured channel plugins * fix(gateway): preserve configured channel warning source
…#96359) * test: migrate src/commands tests to shared temp dir helpers * fix(test): remove unused path import in migrate apply test
…penclaw#96293) * fix(cron): clear agentTurn thinking override when patched with null Cron agentTurn patches could clear model/fallbacks/toolsAllow overrides by sending an explicit null, but thinking had no clear path: the patch schema and normalizer dropped thinking:null before it reached the merge logic, and the payload merge only handled string values. Blanking the Thinking/Effort field in the Cron Control UI therefore silently preserved the old value. Add thinking:null support across the patch schema, exported type, normalizer, and payload merge (mirroring model). The Control UI now sends an explicit clear for model/thinking when an edited job blanks a previously stored override, and the CLI gains --clear-thinking for parity with --clear-model. * docs(cron): document --clear-thinking beside sibling clear flags
…openclaw#96058) Gap finding: tempdir-8h9i0j1k, tempdir-9i0j1k2l Replace bare fs.mkdtemp/mkdtempSync calls in 4 test files with the shared createSuiteTempRootTracker() helper, adding proper cleanup where none existed. Background: the project has standardized on shared temp dir helpers since 88b87d8 (withTempDir) -> 13df67e (createSuiteTempRootTracker) -> 06431fd / openclaw#87298 (CI guard + docs guidance). This PR continues that migration for the highest-risk files. Files changed: - src/skills/lifecycle/install-fallback.test.ts: variable overwrite risk - src/auto-reply/reply/session-hooks-context.test.ts: helper leaks temp dirs - src/auto-reply/reply/abort.test.ts: createAbortConfig leaks root dir - src/auto-reply/inbound.test.ts: test cases without cleanup Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt OOM (openclaw#97693) * fix(discord): bound happy-path API response reads to prevent OOM Replace the unbounded res.text() call in requestDiscord's success path with readResponseTextLimited capped at 4 MiB. Discord channel message lists and attachment payloads can accumulate to large sizes; without a cap the process can exhaust available memory. The error path already used readResponseTextLimited with DISCORD_API_ERROR_BODY_LIMIT_BYTES — this applies the same guard to the happy path using a separate DISCORD_API_RESPONSE_BODY_LIMIT_BYTES constant sized appropriately for valid API payloads. * test(discord): upgrade to real HTTP server proof for bound requestDiscord * fix(discord): remove unnecessary type assertion in bound test
…er (openclaw#97683) Two-step decode in decodeLiteralEscapes: - Step 1: regex anchored to high-surrogate range (U+D800–U+DBFF) so a preceding BMP escape (e.g. \u0041) cannot consume the high-surrogate half of a valid pair like \uD83D\uDE00 (😀), leaving \uDE00 lone. - Step 2: decode remaining BMP codepoints; preserve lone surrogates as six-character literals instead of corrupting them to U+FFFD in the outbound IRC UTF-8 stream.
* fix(utils): keep reply directive ids unicode-safe * test(utils): catch trailing lone surrogate in hasUnpairedSurrogate helper Per PR openclaw#96938 review: the test helper missed a high surrogate at end of string because charCodeAt(out-of-bounds) returns NaN, and NaN comparisons are always false. Guard bounds explicitly so the truncation test actually proves what it claims, plus two cases pinning helper behavior. * chore(utils): rerun QA smoke to confirm memory-index timeout flake on openclaw#96938 --------- Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
openclaw#97814) (openclaw#97857) * fix(memory): detect unindexed session transcripts in status mode (fixes openclaw#97814) The status-purpose MemoryIndexManager init skips ensureSessionStartupCatchup(), so openclaw memory status reports dirty=false while unindexed session files exist on disk. This is a false-clean state: the operator sees no backlog, but memory search silently misses unindexed transcripts. Fix: run markSessionStartupCatchupDirtyFiles() in status mode. It checks for on-disk session files without corresponding memory_index_sources rows and sets sessionsDirty=true if found, without triggering a full sync. The full catchup+sync runs on the next non-transient manager cycle (CLI sync or normal runtime init). Co-Authored-By: Claude <noreply@anthropic.com> * fix(memory): await status dirty detection before status() reads the flag (fixes openclaw#97814) The status-purpose MemoryIndexManager init skips ensureSessionStartupCatchup(), so openclaw memory status reports dirty=false while unindexed session files exist on disk. This is a false-clean state: the operator sees no backlog, but memory search silently misses unindexed transcripts. Fix: move status-mode markSessionStartupCatchupDirtyFiles() from the constructor (fire-and-forget via void) into the create() factory method where it is awaited. This guarantees sessionsDirty is set before any caller reads manager.status(). The detection does NOT trigger a sync, so status remains lightweight. Review: verified manually — unit tests 21/21 pass, compilation 0 errors. * test(memory): add regression test for status-purpose dirty detection (fixes openclaw#97814) Adds a regression test that exercises the actual purpose:'status' manager flow: create a session file without index row, create status manager, verify status().dirty is true. This addresses the ClawSweeper P1 finding requesting a test that exercises the real status path, not only the protected helper. Also fixes the timing issue: move dirty detection from constructor (void) to create() factory (await), guaranteeing sessionsDirty is set before any caller reads manager.status(). --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix(android): clarify gateway auth recovery states * fix(android): preserve retryable pairing recovery copy * fix(android): prefer auth recovery detail before stale address * fix(android): show auth recovery while approval loads
…g seam (openclaw#98205) Add 17 unit tests for nodes-wake-state.ts covering: - Exported wait/poll constants - nodeWakeById Map operations (insert, overwrite, multi-entry, inFlight) - nodeWakeNudgeById Map operations (independent tracking) - clearNodeWakeState function (removal, no-op, scoped deletion) - testing seam (getNodeWakeByIdSize, hasNodeWakeEntry, resetWakeState) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix: surface node approval guidance from devices CLI * fix: preserve node approval connection guidance * fix: handle admin retry unknown device approvals * fix: require stable node approval matches --------- Co-authored-by: welfo-beo <187608477+welfo-beo@users.noreply.github.com> Co-authored-by: welfo-beo <welfo-beo@users.noreply.github.com>
* docs: clarify source checkout Node floor * chore: refresh CI for PR openclaw#97898 --------- Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
… with streamed reasoning (openclaw#94526) * test(telegram): add regression test for forum topic message_thread_id with streamed reasoning After thorough code tracing of all delivery paths (draft stream, durable, non-durable, preview hooks), the current main branch already correctly passes message_thread_id through all paths for the streaming reasoning + final answer scenario in forum topics. The bug reported in openclaw#89352 may have been resolved by earlier merged changes (media-path preservation, draft/progress streaming, etc.). This commit adds a focused regression test covering the combined scenario to prevent future regressions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(telegram): assert forum thread at draft-stream boundary for both lanes --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…nclaw#98145) * fix(device-pairing): don't churn requestId on subset re-requests A reconnect that re-requested a subset of an already-pending device pairing request still superseded it with a fresh requestId. This is the root cause of the "unknown requestId" failures during device approval: 1. A TUI connect files a broad scope-upgrade request; the owner copies its id from `openclaw devices list`. 2. `openclaw devices approve <id>` reconnects as a CLI probe that only needs `operator.pairing` — a subset of the pending scopes. 3. That subset re-request superseded the pending request with a new id, so the originally-listed id no longer existed and approve failed. Refresh the existing request in place when the incoming request only asks for roles/scopes a single pending request (same device key + role) already covers. Escalations that request *more* than the pending request still supersede with a fresh id, so the requestId stays bound to at least the scope snapshot the owner saw (the existing security-motivated behavior and its test are preserved). AI-assisted (Claude Code). * fix(device-pairing): align subset pairing with scope coverage
…he boundary (openclaw#98267) * fix(system-prompt): move exec-approval + Authorized Senders below cache boundary buildExecApprovalPromptGuidance (channel-varying: CLI /approve vs native approval UI) and buildUserIdentitySection / "## Authorized Senders" (owner/identity-varying, dropped when minimal) were emitted into the static, cacheable prefix *above* SYSTEM_PROMPT_CACHE_BOUNDARY. They fork the cacheable prefix at ~token 1,460, invalidating client-side prefix caching for the rest of the ~17.8K-token system prompt — causing minutes-long cold prefills on local models (llama.cpp / MLX / Ollama) after any channel-varying cron/heartbeat turn. Follow-on to openclaw#40256, which moved Messaging/Voice/Reactions below the boundary but missed these two. Relocates both into the existing below-boundary channel-guidance block. Pure cache-stability change with no behavioural change (the guidance is position-independent for correctness). Extends the boundary test to assert both sections sit below SYSTEM_PROMPT_CACHE_BOUNDARY. Measured on a local deployment: shared cross-channel prefix grew ~1,460 -> ~15,486 tokens; post-cron interactive turns went from minutes to ~10s. Fixes openclaw#98261 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Hz9UEpxQ4W3d8XecvupH * fix(system-prompt): suppress relocated exec-approval line under tool_call_style override Addresses review (clawsweeper): the exec-approval guidance lived inside the `tool_call_style` fallback, so a provider override of that section previously replaced it. Relocating it below the boundary emitted it unconditionally, which changed behaviour for providers/plugins that override `tool_call_style`. Gate the relocated line on the absence of a `tool_call_style` override, restoring the original "override replaces the whole section" contract. Extends the provider-override test to assert the default approval line is suppressed when the section is overridden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Hz9UEpxQ4W3d8XecvupH * fix(system-prompt): tighten cache boundary proof * fix(system-prompt): tighten cache boundary proof * fix(system-prompt): tighten cache boundary proof --------- Co-authored-by: headbouyJB <23249268+headbouyJB@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(openrouter): send explicit auth headers * test(openrouter): type stream mock calls
Render Control UI item and preamble progressText events as chat stream segments and preserve pre-final stream commentary before appending final assistant messages. Keyed preamble segments stay independent from accumulated stream snapshots, so distinct same-text commentary items render intact. Co-authored-by: Chisel <chisel@psiclawops.dev>
Co-authored-by: Chisel <chisel@psiclawops.dev>
Add a per-viewer 'Keep commentary' toggle (UiSettings.chatPersistCommentary, default true) that controls whether keyed Codex preamble/commentary blocks stay after the final answer or clear with it. - Persist (default): keyed commentary materializes as durable blocks, current behavior, existing proof unchanged. - Transient (toggle off): commentary stays live during streaming but is never materialized, so it disappears as the final message arrives. This is the transient-only behavior from openclaw#92236, now user-selectable instead of a maintainer-level either/or policy choice. Single gating point in materializeVisibleStreamState (skip itemId-keyed parts when persistCommentary is false); threaded from settings through the chat event handler. Adds desktop + mobile header toggles and an en.ts label (locale bundles regenerated via ui:i18n:sync, English fallback). Tests: reconciliation persist/transient coverage, final-event handler honors the setting, settings round-trip + header button assertions updated.
Keyed preamble commentary was appended after the whole tool loop, so it relied solely on the final visible-time sort for placement and lost the insertion-order tiebreaker against tool cards. Splice each keyed commentary segment into the items list before the first item with a strictly-later timestamp, so a preamble that arrived before a later tool renders above that tool while the run is live (not only after final materialization). Tools sharing the commentary timestamp that are already visible stay above it. Adds a buildChatItems regression covering a keyed preamble between two tools.
* test: update transcript helper routing expectation * test: update transcript helper routing expectation --------- Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Squashed from PR openclaw#77539 after maintainer CI repair.
Remove the pull_request_target labeled-path bypass that unconditionally authorized triage-level actors. All trigger paths now enforce admin, maintain, or write collaborator permission before secret-bearing jobs run. Co-authored-by: Cursor <cursoragent@cursor.com>
Update workflow expectations after removing the pull_request_target labeled-path authorization bypass. Co-authored-by: Cursor <cursoragent@cursor.com>
Dependency GuardThis PR changes dependency-related files. Maintainers should confirm these changes are intentional. Changed files:
Maintainer follow-up:
|
Dependency graph changes notedThis PR includes dependency graph changes. The dependency guard is informational because the PR author is a repository admin or a member of
Security review is still recommended before merge when the dependency graph change is intentional. |
shrad3r
added a commit
that referenced
this pull request
Jul 1, 2026
Fork-only security fix: remove pull_request_target labeled-path auth bypass. Reverts accidental upstream bulk import from PR #4 squash merge. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
Security fix: remove
pull_request_targetlabeled-path authorization bypass inmantis-telegram-desktop-proof.yml.Summary
Evidence
Made with Cursor