Problem
regluit/settings/prod.py (rendered from prod.py.j2) registers 11 scheduled jobs under the if 'prod' == 'prod': branch. Most of these date from the active-campaign era (pre-April 2024) and are likely no-ops or near-no-ops in 2026, but they continue to fire on schedule against a production DB and broker.
Inventory (from prod's rendered prod.py):
| Job key |
Task constant |
Likely 2026 status |
update_active_campaign_statuses |
UPDATE_ACTIVE_CAMPAIGN_STATUSES |
Likely no-op — campaigns ended April 2024 |
report_new_ebooks |
EBOOK_NOTIFICATIONS_JOB |
Probably still relevant — DOAB-driven |
notify_ending_soon |
NOTIFY_ENDING_SOON_JOB |
Likely no-op — nothing ending |
update_account_statuses |
UPDATE_ACCOUNT_STATUSES |
Likely no-op — pledger accounts dormant |
notify_expiring_accounts |
NOTIFY_EXPIRING_ACCOUNTS |
Likely no-op |
refresh_acqs |
REFRESH_ACQS_JOB |
Overwritten in same dict by NOTIFY_UNCLAIMED_GIFTS (bug?) |
refresh_acqs |
NOTIFY_UNCLAIMED_GIFTS |
Likely no-op — no active gifts |
save_info_page |
SAVE_INFO_PAGE |
Generates daily metrics-YYYY-MM-DD.html — still firing |
periodic_cleanup |
PERIODIC_CLEANUP |
Active — runs clearsessions + cleanupregistration |
emit_notices |
EMIT_NOTICES |
Active — user notification queue |
feature_new_work |
FEATURE_NEW_WORK |
Rotates featured work; may or may not still matter UX-wise |
Bonus bug: refresh_acqs is declared twice in the schedule dict — second declaration silently overwrites the first. Either intentional (one is dead code) or a paste error from years ago.
Why audit this
- Each scheduled job that no longer does anything is wasted broker traffic and DB load — small per-job, but accumulates
- The schedule is a maintenance hazard: dead constants like
SEND_TEST_EMAIL_JOB lurked in this file for years before triggering security-private#13. Pruning what's dead reduces the surface area for the next "rogue email" class of incident.
- A small, reviewed, well-named schedule is a forcing function for honest documentation of what prod actually does on a cadence
Proposed approach
- Read each task in
regluit/core/tasks.py and trace what it does today
- Categorize as: keep / prune / rewrite-into-cron-job
- Cron candidates: anything that's better expressed as
manage.py <command> on a cadence (cf. periodic_cleanup calling clearsessions + cleanupregistration)
- Single PR removing the dead entries from
prod.py.j2 + their constants from common.py + their task functions if no other caller
- Validate by re-running through the falsification check (
Received task lines for surviving jobs only) post-deploy
Coordinate with
Decision-needed-before-coding
Eric should confirm which of the "likely no-op" jobs actually have user-visible value in post-campaign mode. Some may still be reachable from admin tools or rare edge cases (e.g., a pledger logging in after years could trigger update_account_statuses semantics). Don't prune blind.
Related
Problem
regluit/settings/prod.py(rendered fromprod.py.j2) registers 11 scheduled jobs under theif 'prod' == 'prod':branch. Most of these date from the active-campaign era (pre-April 2024) and are likely no-ops or near-no-ops in 2026, but they continue to fire on schedule against a production DB and broker.Inventory (from prod's rendered
prod.py):update_active_campaign_statusesUPDATE_ACTIVE_CAMPAIGN_STATUSESreport_new_ebooksEBOOK_NOTIFICATIONS_JOBnotify_ending_soonNOTIFY_ENDING_SOON_JOBupdate_account_statusesUPDATE_ACCOUNT_STATUSESnotify_expiring_accountsNOTIFY_EXPIRING_ACCOUNTSrefresh_acqsREFRESH_ACQS_JOBNOTIFY_UNCLAIMED_GIFTS(bug?)refresh_acqsNOTIFY_UNCLAIMED_GIFTSsave_info_pageSAVE_INFO_PAGEmetrics-YYYY-MM-DD.html— still firingperiodic_cleanupPERIODIC_CLEANUPclearsessions+cleanupregistrationemit_noticesEMIT_NOTICESfeature_new_workFEATURE_NEW_WORKBonus bug:
refresh_acqsis declared twice in the schedule dict — second declaration silently overwrites the first. Either intentional (one is dead code) or a paste error from years ago.Why audit this
SEND_TEST_EMAIL_JOBlurked in this file for years before triggering security-private#13. Pruning what's dead reduces the surface area for the next "rogue email" class of incident.Proposed approach
regluit/core/tasks.pyand trace what it does todaymanage.py <command>on a cadence (cf.periodic_cleanupcallingclearsessions+cleanupregistration)prod.py.j2+ their constants fromcommon.py+ their task functions if no other callerReceived tasklines for surviving jobs only) post-deployCoordinate with
report_new_ebookssurvives the audit and we move it to cron, that's the same conversation.beat.logdirectly.Decision-needed-before-coding
Eric should confirm which of the "likely no-op" jobs actually have user-visible value in post-campaign mode. Some may still be reachable from admin tools or rare edge cases (e.g., a pledger logging in after years could trigger
update_account_statusessemantics). Don't prune blind.Related
prod.py.j2template; the boolean-group_vars cleanup proposal applies here too