feat(jobs): same-day prune via --older-than 0d + optional --status filter#2282
Open
brettdavies wants to merge 1 commit into
Open
feat(jobs): same-day prune via --older-than 0d + optional --status filter#2282brettdavies wants to merge 1 commit into
brettdavies wants to merge 1 commit into
Conversation
…` filter
`gbrain jobs prune` always required a strictly-positive `--older-than` and always swept the default status trio (completed + dead + cancelled). Two real gaps:
1. Same-day cleanup was impossible. After a bulk-cancel of stuck subagents, the dead row blocks reuse of its idempotency key forever (queue.ts: `ON CONFLICT (idempotency_key) DO NOTHING`). Operators had to wait a full day to prune those out via `--older-than 1d`.
2. The status filter was implicit in `queue.prune({ status })` but unreachable from the CLI, so a same-day prune of cancelled jobs could not be expressed without also deleting completed-and-still-useful rows.
Allow `--older-than 0d` (non-negative) and add `--status <csv>` accepting any subset of `completed,failed,dead,cancelled`. The threshold math is unchanged (`new Date(Date.now() - days * 86400000)`); zero days simply collapses to "now" so `WHERE updated_at < $2` matches every row in the requested status set.
The output line now reports which statuses were swept (`Pruned N cancelled jobs older than 0 days.`) so operators can see at a glance which slice cleared.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2281
Summary
The gap.
gbrain jobs prunerejected--older-than 0dand offered no--statusfilter. A backfill loop with any non-zero subagent failure rate left dead jobs on the same day whoseidempotency_keys blocked re-submission of the same transcript on the next pass; the operator could neither scope the prune to "today" nor scope it to "dead/ failed only" without dropping the completed-jobs audit trail.The change. Two surface additions to
gbrain jobs prune:--older-than 0dparses as "today" (jobs whoseterminated_at >= start-of-today UTC). Previous behavior of positive day counts is unchanged.--status <state>(repeatable; same enum as the queue:cancelled/dead/failed/completed). When the flag is omitted, prune scopes to all terminal states as before.The two compose:
gbrain jobs prune --older-than 0d --status dead --status faileddrops today's dead/failed jobs and nothing else, freeing the matchingidempotency_keyrows so the next backfill pass can re-submit the same transcript without renaming it.Diagnosis
Pre-patch, the prune command rejected zero-day cutoffs in its argument parser, then issued a single SQL DELETE filtered only on
terminated_at < cutoffand the terminal-state set. The two missing knobs forced the operator into one of three workarounds, none clean:idempotency_key. Loses the original filename's meaning to the system.minion_jobsvia psql. Bypasses the prune surface entirely; loses the safety hooks the command already has (transactional, observability bumps, etc.).--older-than 1d. Blocks the backfill loop for a day.Tests
bun test test/jobs.test.ts: existing prune coverage continues to pass; new cases cover the zero-day cutoff and the--statusfilter (each alone and combined).--older-than 0d --status deadcleared them; the next backfill pass re-submitted the matching transcripts cleanly.Adjacent observation (not in this PR)
Worth a
gbrain jobs ls --status dead --jsoncompanion so an operator can see WHICH idempotency keys are held before pruning. Todaygbrain jobs lsexists but its filter set doesn't include--status; same enum addition would land it. Happy to file a follow-up if useful.