22import { note } from "../../../../packages/terminal-core/src/note.js" ;
33import { formatCliCommand } from "../../../cli/command-format.js" ;
44import type { OpenClawConfig } from "../../../config/types.openclaw.js" ;
5- import { loadCronQuarantineFile , resolveCronJobsStorePath } from "../../../cron/store.js" ;
5+ import {
6+ CRON_QUARANTINE_MAX_BYTES ,
7+ loadCronQuarantineFile ,
8+ resolveCronJobsStorePath ,
9+ } from "../../../cron/store.js" ;
610import type { HealthFinding } from "../../../flows/health-checks.js" ;
711import { shortenHomePath } from "../../../utils.js" ;
812import type { DoctorPrompter , DoctorOptions } from "../../doctor-prompter.js" ;
@@ -13,6 +17,11 @@ import {
1317 type LegacyCronRepairResult ,
1418 type LegacyCronRepairState ,
1519} from "./legacy-repair.js" ;
20+ import {
21+ archiveOversizedCronQuarantineSidecar ,
22+ formatArchivedQuarantineNote ,
23+ isOversizedCronQuarantineSidecar ,
24+ } from "./oversized-quarantine.js" ;
1625import {
1726 formatLegacyIssuePreview ,
1827 formatUnresolvedCommandPromptAdvisory ,
@@ -138,6 +147,18 @@ export async function collectLegacyCronStoreHealthFindings(params: {
138147 rawJobs,
139148 } = state ;
140149
150+ if ( isOversizedCronQuarantineSidecar ( quarantinePath ) ) {
151+ findings . push (
152+ legacyCronStoreFinding ( {
153+ message : `Cron quarantine sidecar at ${ shortenHomePath ( quarantinePath ) } exceeds the ${ CRON_QUARANTINE_MAX_BYTES } byte safety cap.` ,
154+ path : quarantinePath ,
155+ requirement : "cron-quarantine-oversized" ,
156+ fixHint : `Run ${ formatCliCommand ( "openclaw doctor --fix" ) } to archive the oversized sidecar and start fresh.` ,
157+ } ) ,
158+ ) ;
159+ return findings ;
160+ }
161+
141162 try {
142163 const quarantine = await loadCronQuarantineFile ( quarantinePath ) ;
143164 if ( quarantine . jobs . length > 0 ) {
@@ -276,6 +297,26 @@ export async function maybeRepairLegacyCronStore(params: {
276297 sqliteProjectionBackfillCount,
277298 rawJobs,
278299 } = state ;
300+ if ( isOversizedCronQuarantineSidecar ( quarantinePath ) ) {
301+ note (
302+ [
303+ `Cron quarantine sidecar at ${ shortenHomePath ( quarantinePath ) } exceeds the ${ CRON_QUARANTINE_MAX_BYTES } byte safety cap.` ,
304+ `- The runtime cannot safely load the existing sidecar; it must be archived before new quarantine writes can proceed.` ,
305+ ] . join ( "\n" ) ,
306+ "Cron" ,
307+ ) ;
308+ const shouldArchive = await params . prompter . confirm ( {
309+ message : "Archive the oversized quarantine sidecar now?" ,
310+ initialValue : true ,
311+ } ) ;
312+ if ( shouldArchive ) {
313+ const archivePath = archiveOversizedCronQuarantineSidecar ( quarantinePath ) ;
314+ note (
315+ formatArchivedQuarantineNote ( { archivePath, originalPath : quarantinePath } ) ,
316+ "Doctor changes" ,
317+ ) ;
318+ }
319+ }
279320 try {
280321 const quarantine = await loadCronQuarantineFile ( quarantinePath ) ;
281322 if ( quarantine . jobs . length > 0 ) {
0 commit comments