Skip to content

fix(cron): reset session for stateless cron jobs, not stateful ones#1262

Merged
mrgoonie merged 1 commit into
nextlevelbuilder:devfrom
zezaeoh:fix/cron-stateless-session-reset
Jun 23, 2026
Merged

fix(cron): reset session for stateless cron jobs, not stateful ones#1262
mrgoonie merged 1 commit into
nextlevelbuilder:devfrom
zezaeoh:fix/cron-stateless-session-reset

Conversation

@zezaeoh

@zezaeoh zezaeoh commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Problem

Cron runs reset the session before each run (so a previous run's tool errors can't pollute the next — #294). That reset was gated on if !job.Stateless, which inverts the flag:

  • stateless = true (the default, documented as "saves tokens" / fresh each run) → reset skipped → session accumulates unbounded history across runs.
  • stateless = false (stateful, wants memory) → reset runs every time → session wiped each run.

Observed in production: a frequently-firing stateless=true cron grew its Claude CLI session .jsonl to ~30 MB, replaying the whole history on every run (large token cost) until the model started emitting malformed tool calls.

There's a second layer: the cron reset only cleared the goclaw session store, never the Claude CLI on-disk session. claude-cli resumes its own .jsonl by a deterministic per-key UUID (--resume), so even when the reset fired the model still saw the full accumulated history — i.e. stateless had no effect on the actual model context for claude-cli agents.

Fix

  • Gate the reset on if job.Stateless (correct direction).
  • In that branch, also clear the CLI session via ResetCLISession (indirected through an overridable package var for testing), so a stateless run truly starts fresh on both layers.
  • Guard sessionMgr != nil (it is nil in some unit-test setups).

Stateful jobs (stateless=false) now correctly keep their session across runs. Non-claude-cli providers are unaffected — ResetCLISession is a no-op when no CLI session file exists.

Test

cmd/gateway_cron_test.go: new TestCronJobHandler_StatelessResetsSession asserts a stateless run clears both the session store and the CLI session, and a stateful run clears neither (via a fake SessionStore + an overridden cronCLISessionReset).

go build ./...                     ✅
go build -tags sqliteonly ./...     ✅
go vet ./cmd/                        ✅
go test -race ./cmd/                 ✅

No migration / schema / i18n change.

Note for operators

Behavior change: any cron currently set stateless=false that was relying on the (buggy) per-run wipe will now retain its session. Re-check the flag on existing crons — set stateless=true for jobs that should start fresh each run.

The per-run session reset was gated on `!job.Stateless`, inverting the
flag: stateless jobs (the token-saving default) skipped the reset and
accumulated unbounded history, while stateful jobs were wiped every run.

Reset for `job.Stateless` instead, and clear BOTH session layers — the
goclaw session store AND the Claude CLI on-disk .jsonl. claude-cli
resumes its own session by a deterministic per-key UUID, so without
clearing the .jsonl a "stateless" run still replayed the entire
accumulated history (and silently grew it run after run).
@mrgoonie mrgoonie added agent:github-maintain Processed by github-maintain automation maintain:deferred Deferred by maintain workflow labels Jun 23, 2026

@mrgoonie mrgoonie 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.

Summary: This is a focused cron-session fix. It corrects the stateless gate so stateless cron runs reset both the GoClaw session store and the Claude CLI on-disk session, while preserving stateful cron history.

Risk level: Medium

Mandatory gates:

  • Duplicate/prior implementation: overlap found with older open PR #1032, but this PR is the stronger successor because it preserves stateful jobs and also clears the Claude CLI session layer.
  • Project standards: passed; the change is localized to cmd/gateway_cron.go with targeted tests in cmd/gateway_cron_test.go.
  • Strategic necessity: clear value; prevents stateless cron token/history accumulation and fixes the inverted stateful/stateless behavior.
  • CI/checks: green.

Findings:

  • Critical: none.
  • Important: none.
  • Suggestion: after merge, #1032 should be closed as superseded by this implementation.

Verdict: APPROVE

@mrgoonie
mrgoonie merged commit c0531e1 into nextlevelbuilder:dev Jun 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:github-maintain Processed by github-maintain automation maintain:deferred Deferred by maintain workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants