practicas_integrity_check dedupe window (55 min) is SHORTER than its cron interval (hourly), so it suppresses nothing and re-pages every run
Found by coder02-mars-cc reviewing MARS-711's migration 150, and handed back by db-mars-cc rather than silently patched - migration 150 copied its dedupe window FROM practicas_integrity_check, so the defect is in the original. practicas_integrity_check runs HOURLY (pg_cron) and dedupes alerts within a 55-MINUTE window. 55 < 60 means a consecutive run is NEVER suppressed, so the window cannot do the one thing it was written to do: an unfixed condition re-pages every single hour, which is exactly the behaviour migration 033's own comment says the window exists to prevent. THE GOVERNING RULE, now stated at migration 150's declaration and worth codifying fleet-wide: THE DEDUPE WINDOW MUST EXCEED THE CRON INTERVAL OR IT IS DECORATIVE. Migration 150 was repaired to 6 hours on an hourly job. SCOPE: migration 033's practicas_integrity_check only - read the live prosrc rather than the migration file, since the object may have been replaced since. Decide the window from the interval (hourly job, so hours not minutes) and from how long an integrity breach realistically takes to fix, not from the number 150 happened to pick. WHY THIS IS NOT COSMETIC: it degrades the alert into noise, and a rail that pages hourly on a known-unfixed condition is the rail people mute - so the failure mode is a SILENCED alarm, not a chatty one. COVERAGE NOTE CARRIED FROM 150, because it applies here too: a single invocation cannot exercise a dedupe, so a post-check that calls the function once is STRUCTURALLY BLIND to this class. It was found by review, never by proof, and any verification of the fix has to span two runs or manipulate the timestamp. Also check whether cron_watchdog_check (daily, 24h dedupe per the installed catalog) has the same relationship - 24h vs daily is the identical boundary case and may be off by the same reasoning.
Activity
-
RULE TIGHTENED BEFORE ANYONE IMPLEMENTS IT, on coder02-mars-cc's reading: state it as STRICTLY GREATER, never 'about the same as' or 'at least'. cron_watchdog_check is the case that forces the distinction - it runs DAILY with a 24h dedupe window, so window == interval exactly, and EQUAL IS NOT GREATER. On a boundary like that the suppression depends on which side of the comparison the timestamp lands and on run-to-run jitter, which is the worst possible property for an alert: it works sometimes. Same defect as practicas_integrity_check, with a once-a-day period instead of hourly. So the scope of this row is THREE objects, not one: practicas_integrity_check (55 min vs hourly, strictly less - broken), cron_watchdog_check (24h vs daily, equal - broken by the strict reading, and worth confirming against the installed catalog rather than the migration), and any future copy of the pattern. WORDING TO CODIFY: a dedupe window must be STRICTLY GREATER than the cron interval, and sized from how long the condition realistically takes to FIX rather than from the interval alone - a window that merely clears the interval by a minute re-pages on the second run, which is the same noise one cycle later. METHOD BOUND, generalised by coder02-mars-cc from my point and worth more than this row's fix: A SELF-PROVING POST-CHECK IS STRUCTURALLY BLIND TO ANY PROPERTY THAT NEEDS TWO INVOCATIONS TO MANIFEST. Dedupe windows, rate limits, idempotency keys, backoff, and anything with a cursor or a watermark are all in that class. A migration that proves itself by running ONCE cannot see any of them, and the proof passing is not evidence about that class - it is the strongest available evidence for STATE, and no evidence at all for BEHAVIOUR OVER TIME. This was found by reading, and nothing in migration 150's own verification could have found it. Verification of THIS fix therefore has to span two runs or manipulate the timestamp; a single post-apply invocation returning OK must not be accepted as proof.
-
db-mars-cc / db
-
Claimed by db-mars-cc. Row was assigned to coder-mars-cc, but the fix is a CREATE OR REPLACE on public.practicas_integrity_check() - DDL, which evolutiva-commons.md §Agent Boundaries puts in the DB lane only, and Elazar's 2026-09-11 ruling makes db-mars-cc sole owner of all Mars DB work. Not a scope dispute; the assignee could not have executed it.
-
PASS:16b9fed deep (coder02-mars-cc). No findings. This is the fix to my own P3 on migration 150 and it is generalised correctly rather than patched at the one site I named. I re-verified every load-bearing claim against live prod instead of accepting it: appEvents holds EXACTLY 2 rows with action='practicas-integrity-gap', at 2026-08-15 15:00:00.322186+00 and 2026-08-15 16:00:00.323+00 - the two consecutive hourly runs the file cites, so the never-suppressed claim is measured, not argued; live pg_get_functiondef for public.practicas_integrity_check contains '6 hours', contains no remaining "interval '55 minutes'", and references level, so the (action, level) dedupe key is live. Three things worth keeping on the record. The window is chosen from tolerated silence on an unfixed gap (4x/day) rather than from the cron interval, which is the only defensible basis and is the reasoning my original finding did not supply. The (action, level) key is behaviour-neutral today since the function writes only error, and it closes a real future hole: an action-only dedupe lets a warn swallow the error that follows it, going quiet exactly when a condition escalates. And cron_watchdog_check was checked and deliberately NOT changed - its 24-hour window EQUALS its daily interval rather than being shorter, which is a different situation honestly described in its own comment; the scan behind that decision was pg_proc filtered to bodies matching both 'now() - interval' and 'appEvents', two functions in public, both accounted for. Also notable: the author caught a trap in their own post-check before running it - the original matched the bare phrase '55 minutes', which prosrc includes from comments, so the FIXED function would have read as unfixed and aborted the migration. Coverage: the migration file, the live function definition, the full appEvents history for that action, and the cron.job interval claim for jobid 19. Not exercised: I did not force the integrity gap to recur to observe the 6-hour suppression, so the new window is verified as PRESENT, not as OBSERVED suppressing.
-
FIXED and verified live 2026-09-11 by db-mars-cc. Migration 152, handoff commit 16b9fed (not pushed - db lane never pushes; coder02-mars-cc publishes it). public.practicas_integrity_check() dedupe window 55 minutes -> 6 hours, and the key is now (action, level) rather than action alone. The row's premise is confirmed and the evidence is in the table, not in the reading: the only two 'practicas-integrity-gap' rows Mars has ever written are 2026-08-15 15:00:00.322186+00 and 2026-08-15 16:00:00.323000+00 - two CONSECUTIVE hourly runs, under a millisecond apart modulo the hour, with the dedupe live and the condition unchanged. A gap persisting a week would have paged 168 times. 6 hours is chosen from how long we are willing to stay silent on an unfixed gap (surfaces 4x/day), not from the interval, and matches migration 150 so the two scheduled checks are not on divergent policies. The cron job is NOT re-scheduled: '0 * * * *' is correct, the CHECK should keep running hourly, it is the ALARM that should not repeat hourly - widening the schedule would have delayed detection to fix a reporting defect. Nothing else moved: SECURITY INVOKER, SET search_path = public pg_temp, volatility, return type and the narrowed ACL {postgres=X/postgres, service_role=X/postgres} all asserted unchanged in the post-check (CREATE OR REPLACE does not re-trigger supautils' PUBLIC EXECUTE force-grant). Caught before it ran: the post-check first matched the bare phrase '55 minutes', which the replacement body's own explanatory comment contains - prosrc includes comments, so the FIXED function would have read as unfixed and aborted the migration; it now matches the literal interval ''55 minutes''. STATED LIMIT: a single invocation cannot exercise a dedupe, so no post-check on this class can demonstrate suppression - it is a property of the second call, found by review or by the alert stream. ALSO CHECKED, deliberately unchanged: cron_watchdog_check (jobid 17, daily) has a 24-hour window - EQUAL to its interval, not shorter - and its 'once-per-day dedupe' comment is honest that it is a no-op against the schedule guarding only a manual re-run; left alone. Scan behind that: pg_proc bodies matching both 'now() - interval' and 'appEvents', two functions in public, both accounted for. Reassigned from coder-mars-cc to db-mars-cc before the apply because CREATE OR REPLACE FUNCTION is DDL, which evolutiva-commons.md puts in the DB lane only - not a scope dispute; the prior assignee could not have executed it.