{"id":1315,"date":"2026-02-15T20:14:30","date_gmt":"2026-02-15T20:14:30","guid":{"rendered":"https:\/\/docs.ai.drawconclusions.org\/?page_id=1315"},"modified":"2026-02-24T12:45:55","modified_gmt":"2026-02-24T12:45:55","slug":"freshness-watchdog","status":"publish","type":"page","link":"https:\/\/docs.ai.drawconclusions.org\/?page_id=1315","title":{"rendered":"Freshness Watchdog"},"content":{"rendered":"<h2>Overview<\/h2>\n<ul>\n<li>Server-side watchdog that alerts when docs or tests freshness goes stale.<\/li>\n<li>Sends direct SMTP email to the admin address in <code>config.xml<\/code> (<code>admin\/email<\/code>).<\/li>\n<\/ul>\n<h2>Data Sources<\/h2>\n<h2>Sources<\/h2>\n<ul>\n<li>Docs freshness: WordPress REST API (<code>\/wp-json\/wp\/v2\/pages<\/code>) to find the most recently modified page.<\/li>\n<li>Tests freshness: <code>\/var\/www\/freshness\/all_tests_cronjob_fresh.html<\/code> mtime.<\/li>\n<\/ul>\n<h2>Staleness Rules<\/h2>\n<ul>\n<li>Docs are stale if the latest WP page <code>modified_gmt<\/code> is older than 2 minutes.<\/li>\n<li>Tests are stale if the cron output HTML mtime is older than 2 minutes.<\/li>\n<li>If both are stale, a single combined alert is sent.<\/li>\n<li>Alerts are throttled via <code>\/var\/www\/freshness\/alerts.json<\/code> and reset when freshness recovers.<\/li>\n<\/ul>\n<h2>Implementation<\/h2>\n<ul>\n<li>Script: <code>server\/var_www\/scripts_server\/notify_stale_jobs.py<\/code>.<\/li>\n<li>SMTP target from <code>server\/var_www\/config.xml<\/code> <code>network\/mailpit_bindings\/smtp<\/code> (fallback from <code>runtime\/backend\/mailer_dsn<\/code>).<\/li>\n<li>Alert recipient: <code>admin\/email<\/code> from <code>\/var\/www\/config.xml<\/code>.<\/li>\n<\/ul>\n<h2>Schedule<\/h2>\n<ul>\n<li>Cron: <code>* * * * * \/usr\/bin\/python3 \/var\/www\/scripts_server\/notify_stale_jobs.py<\/code><\/li>\n<\/ul>\n<p class=\"developerdocs-id-search\" aria-hidden=\"true\">DeveloperDoc ID: dd_id_7029bc89e2<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview Server-side watchdog that alerts when docs or tests freshness goes stale. Sends direct SMTP email to the admin address in config.xml (admin\/email). Data Sources Sources Docs freshness: WordPress REST API (\/wp-json\/wp\/v2\/pages) to find the most recently modified page. Tests freshness: \/var\/www\/freshness\/all_tests_cronjob_fresh.html mtime. Staleness Rules Docs are stale if the latest WP page modified_gmt is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1357,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"doc_category":[5],"doc_layer":[26],"class_list":["post-1315","page","type-page","status-publish","hentry","doc_category-workflow","layer-dd_id_d920cc6a97"],"_links":{"self":[{"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/pages\/1315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1315"}],"version-history":[{"count":5,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/pages\/1315\/revisions"}],"predecessor-version":[{"id":3834,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/pages\/1315\/revisions\/3834"}],"up":[{"embeddable":true,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=\/wp\/v2\/pages\/1357"}],"wp:attachment":[{"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1315"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=%2Fwp%2Fv2%2Fdoc_category&post=1315"},{"taxonomy":"doc_layer","embeddable":true,"href":"https:\/\/docs.ai.drawconclusions.org\/index.php?rest_route=%2Fwp%2Fv2%2Fdoc_layer&post=1315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}