← Back to PRs

#22102: fix(cron): default isolated jobs to fresh sessions with sessionReuse opt-in

by k-velorum open 2026-02-20 18:22 View on GitHub →
docs app: macos app: web-ui gateway cli size: M
## Summary Describe the problem and fix in 2–5 bullets: - Problem: Since `v2026.2.17` / PR `#18031`, isolated cron jobs could reuse a stable session and accumulate prior context across runs. - Why it matters: Stateless periodic jobs became more expensive (token growth) and could drift behavior due to unrelated past context. - What changed: - Added `sessionReuse?: boolean` to cron job model and protocol schema. - Regenerated protocol Swift models for `sessionReuse` so `protocol:check` stays in sync. - Defaulted isolated `cron:` runs to fresh sessions unless `sessionReuse === true`. - Added CLI controls: `cron add --session-reuse`, `cron edit --session-reuse|--fresh-session`. - Added `/cron` New Job UI control for `sessionReuse` (isolated + agentTurn only). - Added isolated job chips in `/cron` list to show `fresh` / `reuse` mode. - Added normalization/store-migration handling for `sessionReuse` (including string coercion and invalid-value cleanup). - Added focused tests for `sessionReuse` normalization, `forceNew` session behavior, and UI payload/render behavior. - Added regression tests for webhook-like session-key reuse and explicit `forceNew` routing decisions. - Updated cron docs to clarify default-fresh isolated behavior and `sessionReuse` opt-in semantics. - Applied `docs/style.css` formatting required by repo `pnpm check` (no behavior change). - What did NOT change (scope boundary): - Webhook/custom session-key reuse behavior from `#18031` remains intact. - Main-session cron behavior is unchanged. ## Change Type (select all) - [x] Bug fix - [ ] Feature - [x] Style - [x] Refactor - [x] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [x] Memory / storage - [ ] Integrations - [x] API / contracts - [x] UI / DX - [x] CI/CD / infra ## Linked Issue/PR - Closes #20092 - Related #18031 ## User-visible / Behavior Changes - Isolated cron jobs with default `cron:<jobId>` session key now run with a fresh session by default. - Users who want cross-run continuity can explicitly opt in with `sessionReuse: true`. - New CLI options are available for this toggle in `cron add` and `cron edit`. - `/cron` New Job screen now includes a `Session reuse` toggle (shown only for isolated agentTurn jobs). - `/cron` job cards now show `fresh`/`reuse` chip for isolated jobs. ## 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`) - If any `Yes`, explain risk + mitigation: ## Repro + Verification ### Environment - OS: macOS (local dev machine) - Runtime/container: Node + pnpm local workspace - Model/provider: N/A - Integration/channel (if any): Cron isolated `agentTurn` - Relevant config (redacted): default session store behavior ### Steps 1. Create an isolated cron job with `payload.kind="agentTurn"` and default session key behavior. 2. Run the job multiple times without setting `sessionReuse`. 3. Verify each run is treated as fresh (no unintended transcript carry-over). 4. Set `sessionReuse: true` and verify continuity can still be opted in. ### Expected - Default isolated cron runs are fresh per run. - Explicit `sessionReuse: true` enables reuse. - Webhook/custom session-key reuse path remains unchanged. ### Actual - Matches expected behavior. ## Evidence Attach at least one: - [x] Failing test/log before + passing after - [x] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) Validation snippets: ```bash pnpm build && pnpm check && pnpm test # => FINAL_STATUS=0 # check: format/tsgo/lint passed # test: 121 files passed, 1153 passed | 1 skipped # note: log includes intermittent worker OOM stack traces, but command exits 0 pnpm exec vitest run --config vitest.unit.config.ts \ src/cron/normalize.test.ts \ src/cron/normalize.session-reuse.test.ts \ src/cron/service.jobs.test.ts \ src/cron/service.store-migration.test.ts \ src/cron/isolated-agent/run.skill-filter.test.ts \ src/cron/isolated-agent/session.force-new-cron.test.ts \ src/cli/cron-cli.test.ts # => 75 passed pnpm exec vitest run --config vitest.gateway.config.ts \ src/gateway/protocol/cron-validators.test.ts # => 6 passed pnpm --dir ui exec vitest run --config vitest.config.ts \ src/ui/controllers/cron.test.ts \ src/ui/views/cron.test.ts # => 18 passed pnpm --dir ui build # => build succeeded # Local OpenClaw instance smoke (isolated OPENCLAW_HOME + local gateway) OPENCLAW_HOME=/tmp/openclaw-pr20092-home node dist/entry.js gateway run \ --bind loopback --port 18790 --force --allow-unconfigured --auth token --token pr20092-token OPENCLAW_HOME=/tmp/openclaw-pr20092-home node dist/entry.js cron add --url ws://127.0.0.1:18790 --token pr20092-token --session isolated --message "smoke job" --every 10m --json OPENCLAW_HOME=/tmp/openclaw-pr20092-home node dist/entry.js cron edit <jobId> --url ws://127.0.0.1:18790 --token pr20092-token --session-reuse OPENCLAW_HOME=/tmp/openclaw-pr20092-home node dist/entry.js cron edit <jobId> --url ws://127.0.0.1:18790 --token pr20092-token --fresh-session OPENCLAW_HOME=/tmp/openclaw-pr20092-home node dist/entry.js cron list --url ws://127.0.0.1:18790 --token pr20092-token --json # => sessionReuse transitions: unset/null -> true -> false ``` ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: - local OpenClaw instance smoke: isolated cron `add/edit/list/rm` with `sessionReuse` transition checks (`null -> true -> false`) - `sessionReuse` normalize path (`true`/`false` string and boolean forms) - invalid `sessionReuse` input cleanup - `forceNew` path in cron session resolution behavior - CLI flag plumbing and protocol validator compatibility - `/cron` UI form toggle visibility and payload forwarding/omission behavior - `/cron` UI job list mode chip rendering (`fresh`/`reuse`) - Edge cases checked: - invalid string values - explicit `true` opt-in vs default behavior - add/edit CLI toggle conflict handling - What you did **not** verify: - full live integration runs across external messaging channels - long-duration production cron soak behavior - full `ui` test suite green status end-to-end (targeted cron UI tests were run and passed) ## CI Status - Initial CI failure on `checks (node, protocol, pnpm protocol:check)` was due to generated Swift protocol models not yet updated after `sessionReuse` schema change. - Follow-up commit regenerated Swift protocol models: - `apps/macos/Sources/OpenClawProtocol/GatewayModels.swift` - `apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift` - Remaining CI state should be evaluated on latest head commit. ## Compatibility / Migration - Backward compatible? (`Yes`) - Config/env changes? (`No`) - Migration needed? (`No`) - If yes, exact upgrade steps: ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: - Set affected jobs to `sessionReuse: true` to restore continuity behavior. - Revert commits `d93e75e317e7f3c1849a2a9ba62a3394f7032a80`, `abd938b1569ea8bdecaed6600420c6e456c23bb7`, `9fe78f2328a1bfc9edc37bd93626f42bd3980d51`, `2cfb8f85df4bb08618209d93dd04b4ae3575e8d9`, `137d2331b7714511c443c0e728536deb035673ea`, `5ee4eb01981442aad00a2af6b9fd46ec97330e97`, `77119da4844e98f7c12c4d59e7fce45fed8f2fa8`. - Files/config to restore: - `docs/style.css` - `src/cron/isolated-agent/run.ts` - `src/cron/types.ts` - `src/cron/normalize.ts` - `src/cron/service/jobs.ts` - `src/cron/service/store.ts` - `src/gateway/protocol/schema/cron.ts` - `apps/macos/Sources/OpenClawProtocol/GatewayModels.swift` - `apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift` - `src/cli/cron-cli/register.cron-add.ts` - `src/cli/cron-cli/register.cron-edit.ts` - `ui/src/ui/ui-types.ts` - `ui/src/ui/app-defaults.ts` - `ui/src/ui/types.ts` - `ui/src/ui/controllers/cron.ts` - `ui/src/ui/views/cron.ts` - Known bad symptoms reviewers should watch for: - jobs that expected implicit session continuity losing context between runs ## Risks and Mitigations List only real risks for this PR. Add/remove entries as needed. If none, write `None`. - Risk: Some existing cron jobs may have implicitly depended on session reuse. - Mitigation: `sessionReuse: true` opt-in preserves reuse explicitly. - Risk: Input coercion could accept malformed values if not covered. - Mitigation: Added normalization tests for valid/invalid forms. - Risk: Cross-surface contract drift (types/schema/CLI/runtime). - Mitigation: Updated all relevant layers and validated with unit + gateway protocol tests. ## AI Assistance Disclosure - AI-assisted: Yes - Human review and verification performed: Yes - Testing degree: full `build && check && test` was run with `FINAL_STATUS=0`; test logs include intermittent worker OOM traces while summaries remain all-green. - External model consultation: GLM-5 was used for bug/regression validation and pre-PR quality gate review. - Prompts/session logs: consultation prompts and outputs are summarized in review notes and can be provided on request.

Most Similar PRs