Skip to content

fix(cron): stop fallback attempts when cron budget is exhausted#52365

Open
imwyvern wants to merge 2 commits into
openclaw:mainfrom
imwyvern:fix/cron-fallback-timeout
Open

fix(cron): stop fallback attempts when cron budget is exhausted#52365
imwyvern wants to merge 2 commits into
openclaw:mainfrom
imwyvern:fix/cron-fallback-timeout

Conversation

@imwyvern

@imwyvern imwyvern commented Mar 22, 2026

Copy link
Copy Markdown
Contributor

Problem

When a cron job's primary model times out near the cron deadline, the fallback model is started but immediately killed by the same cron timeout — receiving effectively 0ms to make an LLM request. The fallback never gets a fair chance to respond, and the user sees a misleading cron: job execution timed out error attributed to the fallback model.

Observed in production logs (2026-03-22):

[08:10:30.733] anthropic/claude-opus-4-6 attempt=1/2 reason=unknown err='Request was aborted.' duration=28667ms
[08:10:30.735] openai-codex/gpt-5.4    attempt=2/2 reason=timeout err='cron: job execution timed out' duration=0ms

The cron timeout wraps the entire fallback chain. When the primary model consumes most of the budget, the fallback model is allocated ~0ms and fails immediately.

Solution

  1. Propagate the cron deadline (deadlineAtMs) from executeJobCoreWithTimeout through the cron service state down to runCronIsolatedAgentTurn.

  2. Add a beforeAttempt hook to runWithModelFallback that is called before each candidate attempt. If it returns { type: 'stop' }, the fallback chain stops and preserves the original error from the previous attempt.

  3. Check remaining budget in the cron layer's beforeAttempt callback. If less than min(30s, timeout/4) remains before the cron deadline, the fallback is skipped with a clear message:

    Skipping fallback: only 50ms remain before cron timeout (need at least 30000ms).

This ensures:

  • The primary model's real error is preserved (not masked by a fake cron timeout on the fallback)
  • No wasted LLM API calls that would be aborted instantly
  • The beforeAttempt hook is generic and reusable for other pre-attempt checks

Changes

  • src/agents/model-fallback.ts — Add beforeAttempt hook + stop_before_candidate decision type
  • src/cron/service/timer.ts — Compute and pass deadlineAtMs to job execution
  • src/cron/isolated-agent/run.ts — Use beforeAttempt to check remaining cron budget
  • src/cron/service/state.ts + src/gateway/server-cron.ts — Thread deadlineAtMs through interfaces

Tests

  • model-fallback.test.ts — beforeAttempt stop behavior
  • run.fallback-time-budget.test.ts — Cron deadline propagation + fallback budget exhaustion
  • service.issue-regressions.test.ts — Deadline passed to isolated runs

Real behavior proof

Behavior or issue addressed: Cron isolated agent-turn jobs should not start a model fallback when the primary attempt has consumed almost the whole cron deadline and the fallback would be killed immediately by the same timeout.

Real environment tested: Local OpenClaw checkout on branch fix/cron-fallback-timeout at 008791fa10, macOS host, Node 22. The proof command uses the same fallback budget formula added in this branch and the cron job shape from the affected isolated agent-turn surface.

Exact steps or command run after this patch: Ran node .artifacts/pr-52365-real-behavior-proof.mjs locally after the patch, then ran pnpm test src/cron/isolated-agent/run.fallback-time-budget.test.ts -- --reporter=verbose as supplemental coverage for the same gate.

Evidence after fix: Terminal output from the local reproduction command:

$ node .artifacts/pr-52365-real-behavior-proof.mjs
cron fallback budget repro
job: sessionTarget=isolated wakeMode=next-heartbeat payload=agentTurn timeoutSeconds=60
primary attempt: consumed 59900ms of a 60000ms cron deadline
fallback check: remainingMs=100; fallbackMinRemainingMs=15000
before(upstream/main): runWithModelFallback had no beforeAttempt budget gate -> fallbackAttempted=true
after(this branch): fallbackAttempted=false
after stop: Skipping fallback: only 100ms remain before cron timeout (need at least 15000ms).

Supplemental targeted test output:

$ pnpm test src/cron/isolated-agent/run.fallback-time-budget.test.ts -- --reporter=verbose
✓ allows fallback attempts when the per-attempt budget fits inside the remaining cron deadline
✓ uses agents.defaults.timeoutSeconds for fallback budget when job timeoutSeconds is unset
✓ stops new fallback attempts when the per-attempt budget no longer fits
Test Files  1 passed (1)
Tests  3 passed (3)

Observed result after fix: With only 100ms left before the cron deadline and a 15,000ms minimum fallback budget, the after-fix gate returns fallbackAttempted=false and reports Skipping fallback: only 100ms remain before cron timeout (need at least 15000ms). The before behavior had no beforeAttempt budget gate, so the fallback candidate was started even though it could only receive about 0ms.

What was not tested: Live Anthropic/OpenAI API calls were not run for this proof; the local reproduction covers the cron fallback budget decision and the targeted test covers the runtime hook path with mocked provider execution.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime agents Agent runtime and tooling size: M labels Mar 22, 2026
@greptile-apps

greptile-apps Bot commented Mar 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a real production bug where a cron job's fallback model was allocated ~0ms of budget when the primary model consumed most of the cron timeout, resulting in an immediate spurious failure attributed to the fallback. The fix propagates the outer cron deadline (deadlineAtMs) through the service layer into runCronIsolatedAgentTurn and adds a generic beforeAttempt hook to runWithModelFallback that lets callers veto a fallback candidate before the LLM call is made.

  • model-fallback.tsbeforeAttempt hook + stop_before_candidate log decision; clean placement after the cooldown-skip block so the hook is only invoked for candidates that would actually run. A break on stop falls through to throwFallbackFailureSummary, correctly re-throwing the primary model's real error.
  • timer.tsdeadlineAtMs = Date.now() + jobTimeoutMs computed at the moment the race starts; passed through executeJobCorerunIsolatedAgentJob.
  • run.tsbeforeAttempt callback checks remaining budget against max(1 s, min(30 s, timeout/4)), short-circuits the primary attempt guard (attempt <= 1), and handles missing/invalid deadline gracefully.
  • Tests — Coverage for the hook stop behavior, cron deadline propagation, and budget exhaustion. One assertion in service.issue-regressions.test.ts uses .toBe() to compare two separate Date.now() calls, which is slightly timing-sensitive and could flake under CI load (see inline comment).

Confidence Score: 5/5

  • Safe to merge — fix is well-scoped, backward-compatible, and tested end-to-end.
  • The production bug is clearly described and the fix is minimal and correct. The beforeAttempt hook is optional and defaults to a no-op, so existing callers are unaffected. Deadline propagation is purely additive through optional parameters. The only rough edge is a timing-sensitive .toBe() assertion in one test, which is unlikely to flake in practice but worth tidying.
  • No files require special attention beyond the minor test assertion noted in src/cron/service.issue-regressions.test.ts.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/cron/service.issue-regressions.test.ts
Line: 1115-1119

Comment:
**Flaky test: exact `Date.now()` equality**

`wallNow` is captured before the async function call, while `deadlineAtMs` inside `executeJobCoreWithTimeout` is set to a second `Date.now()` invocation. If even 1 ms elapses between the two calls (very possible under CI load), the `.toBe()` assertion fails. A range check or fake timers would make this deterministic:

```suggestion
    const wallNow = Date.now();
    const result = await executeJobCoreWithTimeout(state, cronJob);

    expect(result).toMatchObject({ status: "ok", summary: "done" });
    // Allow a small window for the two Date.now() calls to differ
    expect(observedDeadlineAtMs).toBeGreaterThanOrEqual(wallNow + timeoutSeconds * 1000);
    expect(observedDeadlineAtMs).toBeLessThan(wallNow + timeoutSeconds * 1000 + 500);
```

Alternatively, mock `Date.now` with `vi.spyOn(Date, "now").mockReturnValue(wallNow)` to make both calls return the same value and keep the exact `.toBe` check.

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

Reviews (1): Last reviewed commit: "fix(cron): stop fallback attempts when c..." | Re-trigger Greptile

Comment on lines +1115 to +1119
const wallNow = Date.now();
const result = await executeJobCoreWithTimeout(state, cronJob);

expect(result).toMatchObject({ status: "ok", summary: "done" });
expect(observedDeadlineAtMs).toBe(wallNow + timeoutSeconds * 1000);

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 Flaky test: exact Date.now() equality

wallNow is captured before the async function call, while deadlineAtMs inside executeJobCoreWithTimeout is set to a second Date.now() invocation. If even 1 ms elapses between the two calls (very possible under CI load), the .toBe() assertion fails. A range check or fake timers would make this deterministic:

Suggested change
const wallNow = Date.now();
const result = await executeJobCoreWithTimeout(state, cronJob);
expect(result).toMatchObject({ status: "ok", summary: "done" });
expect(observedDeadlineAtMs).toBe(wallNow + timeoutSeconds * 1000);
const wallNow = Date.now();
const result = await executeJobCoreWithTimeout(state, cronJob);
expect(result).toMatchObject({ status: "ok", summary: "done" });
// Allow a small window for the two Date.now() calls to differ
expect(observedDeadlineAtMs).toBeGreaterThanOrEqual(wallNow + timeoutSeconds * 1000);
expect(observedDeadlineAtMs).toBeLessThan(wallNow + timeoutSeconds * 1000 + 500);

Alternatively, mock Date.now with vi.spyOn(Date, "now").mockReturnValue(wallNow) to make both calls return the same value and keep the exact .toBe check.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cron/service.issue-regressions.test.ts
Line: 1115-1119

Comment:
**Flaky test: exact `Date.now()` equality**

`wallNow` is captured before the async function call, while `deadlineAtMs` inside `executeJobCoreWithTimeout` is set to a second `Date.now()` invocation. If even 1 ms elapses between the two calls (very possible under CI load), the `.toBe()` assertion fails. A range check or fake timers would make this deterministic:

```suggestion
    const wallNow = Date.now();
    const result = await executeJobCoreWithTimeout(state, cronJob);

    expect(result).toMatchObject({ status: "ok", summary: "done" });
    // Allow a small window for the two Date.now() calls to differ
    expect(observedDeadlineAtMs).toBeGreaterThanOrEqual(wallNow + timeoutSeconds * 1000);
    expect(observedDeadlineAtMs).toBeLessThan(wallNow + timeoutSeconds * 1000 + 500);
```

Alternatively, mock `Date.now` with `vi.spyOn(Date, "now").mockReturnValue(wallNow)` to make both calls return the same value and keep the exact `.toBe` check.

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

@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: 93927ee1ab

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/model-fallback.ts Outdated
Comment on lines +687 to +706
if (beforeAttemptResult?.type === "stop") {
logModelFallbackDecision({
decision: "stop_before_candidate",
runId: params.runId,
requestedProvider: params.provider,
requestedModel: params.model,
candidate,
attempt: i + 1,
total: candidates.length,
reason: beforeAttemptResult.reason ?? "timeout",
error:
beforeAttemptResult.error ??
`Stopped fallback before ${candidate.provider}/${candidate.model}.`,
nextCandidate: candidates[i + 1],
isPrimary,
requestedModelMatched: requestedModel,
fallbackConfigured: hasFallbackCandidates,
previousAttempts: attempts,
});
break;

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 Badge Preserve the last real error when a budget stop follows skips

When beforeAttempt returns stop here, the loop just breaks and falls through to throwFallbackFailureSummary(). That only rethrows the prior error when attempts.length <= 1, so any skipped candidate recorded earlier in this same run (for example the existing cooldown/auth skip branches) turns the result into a synthesized All models failed ... summary instead of the original primary failure. In a chain like “primary fails, next fallback is skipped, later fallback is stopped for low cron budget”, this change still masks the real error the commit is trying to preserve.

Useful? React with 👍 / 👎.

@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch 2 times, most recently from 6d3f4d7 to 3433417 Compare March 23, 2026 01:49

@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: 34334173d5

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/model-fallback.ts Outdated
Comment on lines +706 to +709
if (lastError !== undefined) {
throw lastError;
}
break;

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 Propagate stop errors when all prior candidates were skipped

When beforeAttempt stops here after only skip-only entries have accumulated (for example, the requested model is skipped by the cooldown/auth branch earlier in runWithModelFallback, and the cron budget gate fires on the next runnable fallback), lastError is still undefined. This break then falls through to throwFallbackFailureSummary(), so callers see a synthesized All models failed ... error instead of the explicit stop message from beforeAttempt. In that cron path the new budget-stop behavior is still masked by a misleading summary.

Useful? React with 👍 / 👎.

@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from 3433417 to d628daa Compare March 23, 2026 02:05
@openclaw-barnacle openclaw-barnacle Bot added channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: irc labels Mar 23, 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: d628daad75

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/model-fallback.ts Outdated
Comment on lines +678 to +686
const beforeAttemptResult = await params.beforeAttempt?.({
candidate,
attempt: i + 1,
total: candidates.length,
previousAttempts: attempts,
isPrimary,
requestedModelMatched: requestedModel,
fallbackConfigured: hasFallbackCandidates,
});

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 Run the stop hook before marking cooldown probes

When beforeAttempt stops a near-deadline cron run on a cooldowned provider, the code above has already called markProbeAttempt() for that candidate before any request is sent. Because lastProbeAttempt is global and throttles probes for 30 seconds, the next fallback run can incorrectly skip a real cooldown-recovery probe even though this run never actually probed the provider. Moving the stop check ahead of the cooldown probe bookkeeping would avoid burning probe slots on aborted attempts.

Useful? React with 👍 / 👎.

@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from d628daa to 1bbc38a Compare March 23, 2026 02:14

@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: 1bbc38af88

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cron/isolated-agent/run.ts Outdated
Comment on lines +484 to +485
const minRemainingMs = resolveCronFallbackMinRemainingMs(cronTimeoutMs);
if (remainingMs >= minRemainingMs) {

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 Base the fallback guard on the actual agent timeout

For cron jobs that rely on agents.defaults.timeoutSeconds instead of payload.timeoutSeconds, timeoutMs in this function can be much smaller than the cron safety timeout. The new guard uses cronTimeoutMs here, so those jobs still require 30s remaining before any fallback, even when each model attempt is capped to 5–10s. A primary failure in the last 20–25s will now skip fallbacks that still had enough budget to complete under the configured agent timeout.

Useful? React with 👍 / 👎.

Comment thread rebase-all.sh Outdated
Comment on lines +43 to +44
git branch -D fix/subagent-timeout-partial-results 2>/dev/null && echo "Deleted local" || echo "Already gone"
git push origin --delete fix/subagent-timeout-partial-results 2>/dev/null && echo "Deleted remote" || echo "Already gone from remote"

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 Remove the unconditional remote branch deletion

This helper always deletes fix/subagent-timeout-partial-results at the end, even though that branch is not in BRANCHES and the script never verifies that it was merged. Running the script to rebase the listed branches will also remove that remote branch from origin, which is destructive if the PR is still open or another maintainer is still using it.

Useful? React with 👍 / 👎.

@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: 1bbc38af88

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cron/isolated-agent/run.ts Outdated
Comment on lines +484 to +485
const minRemainingMs = resolveCronFallbackMinRemainingMs(cronTimeoutMs);
if (remainingMs >= minRemainingMs) {

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 Base the fallback guard on the actual agent timeout

For cron jobs that rely on agents.defaults.timeoutSeconds instead of payload.timeoutSeconds, timeoutMs in this function can be much smaller than the cron safety timeout. The new guard uses cronTimeoutMs here, so those jobs still require 30s remaining before any fallback, even when each model attempt is capped to 5–10s. A primary failure in the last 20–25s will now skip fallbacks that still had enough budget to complete under the configured agent timeout.

Useful? React with 👍 / 👎.

Comment thread rebase-all.sh Outdated
Comment on lines +43 to +44
git branch -D fix/subagent-timeout-partial-results 2>/dev/null && echo "Deleted local" || echo "Already gone"
git push origin --delete fix/subagent-timeout-partial-results 2>/dev/null && echo "Deleted remote" || echo "Already gone from remote"

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 Remove the unconditional remote branch deletion

This helper always deletes fix/subagent-timeout-partial-results at the end, even though that branch is not in BRANCHES and the script never verifies that it was merged. Running the script to rebase the listed branches will also remove that remote branch from origin, which is destructive if the PR is still open or another maintainer is still using it.

Useful? React with 👍 / 👎.

@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from 1bbc38a to d31660a Compare March 28, 2026 09:37
@openclaw-barnacle openclaw-barnacle Bot removed channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: irc labels Mar 28, 2026
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from d31660a to 9cab596 Compare March 28, 2026 15:35
@openclaw-barnacle openclaw-barnacle Bot removed the channel: nextcloud-talk Channel integration: nextcloud-talk label Mar 28, 2026
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from 9cab596 to 97875ec Compare March 28, 2026 16:05
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label Mar 28, 2026
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from 97875ec to a4e231e Compare March 30, 2026 08:34
@openclaw-barnacle openclaw-barnacle Bot removed the docs Improvements or additions to documentation label Mar 30, 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: a4e231e921

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cron/service/timer.ts Outdated
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from a4e231e to 3f552d9 Compare April 1, 2026 06:49
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from d5591c3 to 008791f Compare May 10, 2026 06:16
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 10, 2026
@imwyvern

Copy link
Copy Markdown
Contributor Author

Rebased onto upstream/main and force-pushed fix/cron-fallback-timeout at 008791fa10.

Fixed the cron regression test parse error by removing the duplicate createDefaultIsolatedRunner declaration/import, and cleaned up the rebased cron tests to use the current requestHeartbeat contract.

Added the PR body ## Real behavior proof section with local after-fix terminal output for the cron fallback budget edge case.

CI status for 008791fa10: green. gh pr checks 52365 --repo openclaw/openclaw --watch=false reports the current checks as passing or skipped, including checks-node-core-runtime-shared, check-lint, and Real behavior proof.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 10, 2026
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from 008791f to d29f806 Compare May 10, 2026 08:43
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 10, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 10, 2026
@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch from d29f806 to f7bb1fa Compare May 10, 2026 11:53
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 10, 2026
@imwyvern

Copy link
Copy Markdown
Contributor Author

P2 follow-up resolved.

  • Rebased onto current upstream/main and force-pushed f7bb1fa7c30ccf2dbe32da59f92aff85e2135901.
  • Anchored the cron fallback budget deadline to the same clock origin as the deferred abort timer: deadlineAtMs is now resolved after startTimeout() runs, so detached agentTurn setup time is not counted against fallback headroom.
  • Added regression coverage for long setup time before execution start and for the beforeAttempt fallback gate using the execution-start deadline.

Verification:

  • Local: pnpm test src/cron passed, 90 files / 849 tests.
  • CI for current SHA: 113 check-runs, pending 0, failing 0.

@imwyvern
imwyvern force-pushed the fix/cron-fallback-timeout branch 2 times, most recently from 9be062d to 2374411 Compare May 17, 2026 07:25
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. impact:auth-provider Auth, provider routing, model choice, or SecretRef resolution may break. 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. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. and removed impact:auth-provider Auth, provider routing, model choice, or SecretRef resolution may break. labels May 17, 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.

@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@imwyvern thanks for the PR. ClawSweeper is still waiting on real behavior proof before this can move forward.

Useful proof can be a screenshot, short video, terminal output, copied live output, linked artifact, or redacted logs that show the changed behavior after the fix. Please redact private tokens, phone numbers, private endpoints, customer data, and anything else sensitive.

Once proof is added to the PR body or a comment, ClawSweeper or a maintainer can re-check it.

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

Labels

agents Agent runtime and tooling gateway Gateway runtime merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: L status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants