* fix(cron): persist startup catch-up deferral ids in service state to prevent read-RPC clobber
The startup overflow catch-up deferral (#93810) set deferred job
nextRunAtMs to a staggered slot, but the exemption was stored as a
local skipFutureRepairJobIds set threaded only into start()'s
maintenance recompute pass. Every other caller of
recomputeNextRunsForMaintenance — ensureLoadedForRead (list/status),
finalizeCompletedResults, empty-due tick, manual run preflight, and
releaseUnclaimedDueJobReservations — called maintenance recompute
without the skip set, causing shouldRepairFutureCronNextRunAtMs to
advance the deferred staggered slot to the job's natural next run,
dropping the missed run for a full period.
Fix: Move the exemption into CronServiceState as
pendingCatchupDeferralJobIds, populated by applyStartupCatchupOutcomes
where deferrals are assigned. recomputeNextRunsForMaintenance now
always checks this state-level set instead of a local parameter, and
clears each id once its staggered slot is reached (now >= nextRunAtMs).
This gives one canonical exemption path that covers all recompute
callers.
The now-redundant skipFutureRepairJobIds parameter is removed.
Fixes#93935
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(clownfish): address review for repair-94022-fresh-plan-20260618 (1)
* fix(cron): preserve agentTurn exempt + add stale-deferral cleanup + runtime proof
Address ClawSweeper review by:
1. Keeping the existing agentTurn deferred-slot exemption unchanged
(shouldRepairFutureCronNextRunAtMs still returns false for agentTurn
jobs with nextRunAtMs before the natural schedule).
2. Adding cleanup of stale pendingCatchupDeferralJobIds markers for
jobs that no longer exist or are disabled.
3. Adding regression tests for pending startup catch-up deferral
preservation and stale marker cleanup.
4. Adding standalone CLI runtime proof script demonstrating the fix.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: add pendingCatchupDeferralJobIds to test-harness + remove unused import
- Add pendingCatchupDeferralJobIds to createMockCronStateForJobs to fix TS2741.
- Remove unused loadCronStore import from runtime proof script.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(cron): tighten startup catch-up deferral handling
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(gateway): cap agentRunCache to prevent unbounded growth under run fan-out
Time-based prune only reclaims entries past the 10-minute TTL window; a burst
of run fan-out can add far more entries than the window reclaims, so the cache
could grow without bound between prunes. Add a FIFO entry cap (5000) enforced
on insert, mirroring the existing Discord REST entity-cache bound.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(gateway): preserve waited run snapshots under cache cap
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(tlon): bound error response body reads to prevent OOM
Replace bare response.text() on non-ok paths with readResponseTextLimited
capped at 16 KiB so a hostile or misconfigured Urbit ship cannot force the
gateway to buffer an arbitrary-size error body into process memory.
Affected paths:
- pokeUrbitChannel (channel-ops.ts)
- channel.runtime.ts poke path
- sendSubscription (sse-client.ts)
* fix(tlon): fix lint issues in error-body-boundary test
- Remove unused beforeEach import
- Wrap if/else bodies in braces (curly)
- Use block body for Promise executors (no-promise-executor-return)
* fix(types): resolve pre-existing TS test type errors
- Fix TS2493 tuple type errors in server-cron-notifications and
server-cron tests by adding explicit type annotations on mock.calls
- Fix TS2322 in anthropic.test.ts by adding as const to resource
content block type
* chore: trigger CI
* fix(update-check): bound npm registry JSON response read to prevent OOM
- Replace unbounded res.json() with readProviderJsonResponse capped at 16 MiB
- Update test mock to use real Response instead of bare object
- Verified against live npm registry: openclaw update status --json returns latestVersion: 2026.6.11
* fix(update-check): add 4 boundary tests for bounded npm registry read
- Tests: oversized response >16 MiB, near-boundary success
- Tests: malformed JSON, non-200 status code
- All pass with the readProviderJsonResponse bounded reader
* chore: add real behavior proof script for bounded JSON reader
Adds a standalone proof script that starts a local HTTP server and
drives the bounded reader against it with real HTTP requests, showing:
- Normal responses (~1 MB) parse correctly
- Oversized responses (>20 MB) are rejected with a descriptive error
- Malformed JSON is caught
- RSS does not spike on oversized responses
Ref. https://github.com/openclaw/openclaw/pull/98508
* chore: remove PR-specific proof script before merge
The proof script was accepted by ClawSweeper (proof: sufficient,
rating: diamond lobster), but it duplicates repository logic and
fails the scripts lint lane. Removing it per review feedback.
The real behavior proof remains in the PR body.
Ref. https://github.com/openclaw/openclaw/pull/98508
* fix(cli): retry logs.tail after journal fallback in logs follow
Rebase #88159 onto current main and keep systemd journal fallback temporary in follow mode. Preserve the journal cursor across repeated fallback outages, but retry logs.tail on the next loop so recovered Gateway RPC returns to normal log output.
This refresh also replaces the stale red checks-node-core-fast result from the old head with a current-head CI run.
* Keep log source metadata explicit
* ci: retrigger checks for PR #88159
* docs: clarify logs follow JSON source transitions
* fix(cli): keep journal logs responsive during recovery
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(status): bound systemd service probes so status cannot hang on a wedged systemctl (#84698)
* test(daemon): assert readRuntime receives the threaded status timeout opts (#84698)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(cron): preserve provider/model on isolated-run timeout row
* fix(cron): carry provider/model/session into timer-built timeout rows
The reporter's blank cron_run_logs row (cron: job execution timed out
(last phase: ...)) comes from the wall-clock/cancel outcome built in
executeJobCoreWithTimeout, not the inner run catch the prior commit
patched (that catch result loses the Promise.race). Carry the
already-resolved attribution from watchdog-visible execution state into
the timer-built timeout and post-runner cancel outcomes so the persisted
row keeps provider/model/session. Pre-runner setup timeouts stay blank.
Refs #95873
* fix(cron): attribute timeout-disabled isolated-run operator-cancel rows
The timeoutSeconds:0 branch in executeJobCoreWithTimeout has no watchdog,
so it returned createOperatorCancellationOutcome() with no execution data
and never wired the execution callbacks. An operator-cancelled isolated run
with timeouts disabled still wrote a blank provider/model/session row.
Track the resolved identity locally from the same onExecutionStarted/
onExecutionPhase callbacks and carry it into the cancel outcome, matching
the timed branch. Adds a focused regression with negative control (#95873).
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary:
- The PR adds `cursor-agent` as an opt-in autoreview engine, updates the helper docs, runner dispatch, stream filtering, report parsing, and harness allowlists.
- PR surface: Docs +1, Other +99. Total +100 across 4 files.
- Reproducibility: not applicable. this is a feature PR, not a reported bug. The relevant check is source review plus maintainer validation of the external engine path.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 807659492b.
- Required merge gates passed before the squash merge.
Prepared head SHA: 807659492b
Review: https://github.com/openclaw/openclaw/pull/97348#issuecomment-4824183439
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
* fix(cli): show exit code when npm install returns empty output
installPackageDir previously produced 'npm install failed:' with an empty
suffix when npm exited non-zero without writing to stdout or stderr. Users
running 'openclaw plugins install @openclaw/acpx' saw only that empty line
followed by the misleading hook-pack fallback error, leaving nothing
actionable in the output.
Add a small helper that keeps npm's own output when it exists but falls
back to reporting the exit code, signal, and termination reason when both
streams are empty. Regression tests cover the empty-output exit case and
the signal-terminated case; the existing stderr surfacing test still
passes unchanged.
Refs #98484
* fix(cli): narrow npm install failure diagnostics
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(slack): guard relay WebSocket frame JSON.parse against malformed input
Slack Socket Mode relay receives WebSocket frames from external
infrastructure. parseRelayFrame() used bare JSON.parse() which would
throw raw SyntaxError on malformed frames, potentially crashing the
relay connection.
Wrap JSON.parse in try/catch and throw SlackRelayMalformedFrameError
with the original SyntaxError as cause, so callers can distinguish
transport errors from parse errors.
D4 dimension — all competitors have zero coverage.
Signed-off-by: lsr911 <liao.shirong@xydigit.com>
* fix(slack): repair relay frame guard tests
---------
Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Preserve the Tailscale timeout cleanup from #98134 and the Feishu TDZ fix from #98137 while satisfying the repository lint rules.
Credit: @zhangLei99586 authored both underlying fixes.
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: zhangLei99586 <zhang.lei162@xydigit.com>
5.22 already drops the tool-error WARNING text via payloads.ts, but the
error tool-result payload was still delivered as channel progress unless
sourceReplyDeliveryMode was message_tool_only. Operators who opt into
messages.suppressToolErrors expect no tool-error noise in chat at all.
Add a config-gated early-return in the onToolResult dispatch path so the
visible progress delivery is dropped too, matching the warning-text policy.
No-op unless messages.suppressToolErrors is true. Folds the mac-mini deploy
hotfix into the tracked branch.
(cherry picked from commit a973410e6d3ddbbaa4c3fb308ad4247274a9633a)
Co-authored-by: amittell <mittell@me.com>