fix(cron): bound cron quarantine sidecar file reads#101477
Conversation
|
Codex review: needs changes before merge. Reviewed July 19, 2026, 2:16 AM ET / 06:16 UTC. Summary PR surface: Source +132, Tests +140. Total +272 across 6 files. Reproducibility: yes. Current Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Keep the bounded runtime path and Doctor-owned archival migration, but correct the Doctor note to show the captured pre-rename size or say only that the file exceeded the cap before merge. Do we have a high-confidence way to reproduce the issue? Yes. Current Is this the best way to solve the issue? Yes, aside from the diagnostic wording defect. A bounded reader and bounded serialized write with Doctor-owned archival recovery is the narrowest maintainable fit for the repository’s stated legacy-state migration policy. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 25a8b33ff50f. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +132, Tests +140. Total +272 across 6 files. View PR surface stats
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (72 earlier review cycles; latest 8 shown)
|
e35ef7d to
3d2fe22
Compare
|
@clawsweeper re-review\n\nI added real behavior proof to the PR body, including the local test command and output that exercises the oversized-file rejection path. |
3d2fe22 to
74acfe9
Compare
|
@clawsweeper re-review Added real behavior proof that exercises loadCronQuarantineFile from src/cron/store.ts with a normal valid quarantine sidecar and an 8 MiB + 1 byte oversized sidecar. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
132290f to
9fccd94
Compare
|
@clawsweeper re-review Addressed the write-path finding: |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
Behavior ProofCode Changes
Local Verification
Risk AssessmentThis change replaces an unbounded |
Addresses ClawSweeper P1 finding: instead of overwriting a single fixed
archive, each overflow creates a uniquely-named archive
({base}.{ts}.{random}.archive.json). When the count exceeds 5, the oldest
archives are pruned to prevent unbounded disk growth.
…ndidate-checklist
…ead + archive recovery ClawSweeper P1: automatic deletion of recovery archives requires maintainer approval for the retention policy. Remove pruneOldQuarantineArchives and CRON_QUARANTINE_ARCHIVE_MAX_COUNT so no recovery data is silently deleted. All quarantine recovery data is now retained for operator inspection. The active sidecar is still bounded at 8 MiB, and overflow archives are created on demand. Disk growth is naturally bounded by overflow frequency since each archive is at most 8 MiB.
Fix Update: Removed auto-pruning of quarantine archivesPer ClawSweeper P1 finding — automatic deletion of recovery archives requires maintainer approval. Removed The PR now:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review PR body updated with current-head proof (commit 884185e):
|
|
@clawsweeper re-review PR body updated with real runtime proof — production
Proof script inlines the production code paths byte-for-byte from |
|
@clawsweeper re-review PR body updated — the "Real Runtime Proof" section now uses the actual checked-in production module (
No inlined copies — direct |
|
@clawsweeper re-review — removed unused listQuarantineArchives function that was causing CI failures (TS6133, no-unused-vars) on check-prod-types, check-lint, check-test-types, and ci-gate |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review — addressed both P1 findings: (1) restored validateTrustedToolingPin declarations in release-candidate-checklist, (2) removed archive rotation entirely — PR now narrow to bounded caps only (fail-closed on overflow, no recovery archives created) |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Addressed the P1 finding by moving oversized legacy quarantine sidecar handling into Doctor. Changes (head
Focused proof: |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
What Problem This Solves
loadCronQuarantineFilereads the entire cron quarantine sidecar into memory with no size limit. A corrupted or hostile sidecar can OOM the cron load path.saveCronQuarantineFilealso allowed unbounded writes, so a runaway invalid-row stream could grow the sidecar without limit.Additionally, any existing quarantine sidecar already larger than the new safety cap would break after upgrade unless the user has a migration path.
Why This Change Was Made
ClawSweeper review flagged both the unbounded read/write surface and the missing upgrade migration for legacy oversized sidecars. The repository's canonical boundary for legacy persistent-state recovery is
openclaw doctor --fix, not steady-state runtime.What Changed
CRON_QUARANTINE_MAX_BYTES = 8 * 1024 * 1024constant for bounded reads/writes.loadCronQuarantineFileusesreadRegularFilewithmaxBytes— descriptor-level bounded read (replaces unboundedfs.promises.readFile).saveCronQuarantineFilerejects serialized writes that would exceed the cap.CronQuarantineOversizedErrorso callers can distinguish an oversized legacy sidecar from a parse error.src/commands/doctor/cron/oversized-quarantine.ts:{quarantinePath}.oversized.{timestamp}.{random}.archive.json.src/commands/doctor/cron/index.ts:collectLegacyCronStoreHealthFindingsemits acron-quarantine-oversizedfinding.maybeRepairLegacyCronStoreprompts to archive (or auto-archives in--yesmode).src/commands/doctor/cron/index.test.ts.User Impact
openclaw doctor --fixafter upgrade, any existing oversized sidecar is archived and a fresh empty sidecar is started — cron writes can proceed.Evidence (head SHA:
0549437f7ca)Focused Tests — all pass ✓
Terminal Proof — Doctor detects, archives, and restores a usable sidecar
The transcript below was produced at the current head (
0549437f7ca) against a real temp directory.Step 1 —
openclaw doctor --lintdetects the oversized sidecar:Step 2 — Doctor cron repair archives the legacy sidecar:
Step 3 — Post-repair lint is clean and cron quarantine I/O works: