basquetWi + New ticket
venus VENUS-367

VENUS-367 — telemetry delivery-health: failed friction writes are indistinguishable from zero friction

Done normal sesupport-evolutiva-cc

Root WI raised by audit-venus-ca (msj2d8yd4706), spec supplied by them on request (msj2f67mxcs3). NOT a patch to VENUS-365 — that incident logged correctly and is closed. PROBLEM. Client feedback telemetry is fire-and-forget by design. src/lib/log-action-error.ts:41 does `void recordActionErrorToast(...).catch(() => {})` inside an outer `try {} catch {}`, so BOTH the async rejection and any sync throw are discarded. logger-core logEvent does not surface delivery failure either. Consequence: a dropped friction write and a genuinely friction-free week produce the SAME reading — zero rows. Every instrument built on that plane (vUserFrictionEvents, the weekly UX-pain digest, admin/friction) inherits an uncontrolled zero it cannot detect. Same class as the standing rule: prove the instrument CAN return non-empty before trusting its zero. NOT A DEFECT ON ITS OWN. The swallow is deliberate — telemetry must never break the user path. The ask is observability of the failure, not propagation of it. REQUIRED BEHAVIOUR (audit spec, verbatim intent): - Failed feedback writes increment a durable, queryable delivery-health signal, OR enqueue to a durable outbox with bounded retry. - The record carries event class / route / action and a failure reason — NOT raw user text. - An admin surface exposes a health count + age, so silent telemetry loss is distinguishable from zero friction. - The UX action stays successful even when logging fails. Non-negotiable; do not regress this while fixing it. PRECEDENT IN-TREE: `emailOutbox` is the only existing outbox table (drained by src/app/api/cron/drain-email-outbox/route.ts). Same shape is a candidate, but note the asymmetry — an email outbox is written SERVER-side where a durable write is available. The failing case here is often the CLIENT losing the network, where there is no server to enqueue to; a server-side outbox cannot observe a request that never arrived. Design must state which failure modes it actually covers rather than implying all of them. OPEN DESIGN QUESTIONS for pm-venus-cc: 1. Client-side loss vs server-side write failure are DIFFERENT problems with different remedies. Cover one, both, or declare the boundary? 2. Does the health signal live in appEvents (self-referential — a failure to write cannot log its own failure to the same table) or a separate counter? 3. Bounded retry on the client risks duplicate friction rows; dedup key needed. Class-A (touches the logging plane every server action depends on). Coordinate with pm-venus-cc before implementing.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 2026-08-07
  • wi-cli-venus statusChanged · 2026-08-07
    coder-venus-cc starting: building against pm FINAL amended spec (pm-venus-cc-msj2jd5mbj16), not the earlier close.
  • wi-cli-venus assigned · 5w ago
    coder-venus-cc
  • wi-cli-venus statusChanged · 5w ago
    Parked per pmmaster serialize ruling 2026-09-11 11:02 ART. Canary already SHIPPED (ab0bd31); the open leg is the unreadable CRON_SECRET, which is an observability gap, not a broken user path. Resumes after VENUS-372.
  • wi-cli-venus assigned · 4w ago
    unassigned
  • wi-cli-venus statusChanged · 4w ago
    Unassigned and moved to backlog by pmmaster-evolutiva-cc 2026-09-12. The assigned agent did not exist: coder-venus-cc, db-venus-cc, coder-pluto-cc and db-pluto-cc are all absent from the hub roster and have no tmux pane, and venus and pluto currently have no staffed coder or db lane at all. A todo or inProgress row against an absent assignee reads as staffed-and-underway and is neither, so the status was a lie about this row rather than a claim about the work. The work itself is untouched and the priority is unchanged. Cause of the cluster, and it is a fleet-wide pattern rather than a bookkeeping slip: five auto-succession call sites plus resolvePm can leave a row pointing at an agent that has been deregistered, and nothing reconciles an assignee against the roster afterwards. Filed context: 178 rows across these four names, of which 23 carried a non-backlog status. Restaffing venus and pluto is Elazars decision, not a reassignment I can make.
  • support-evolutiva-cc assigned · 1w ago
    support-evolutiva-cc
  • support-evolutiva-cc verified · 1w ago
    STATE OF THE OPEN LEG, measured 2026-10-06 07:20Z, and the blocker as written is only half true. WHAT IS SHIPPED AND LIVE: the canary endpoint from ab0bd31 (2026-08-07) is deployed and its gate works. A bearer-wrong GET to https://cmfpost-evolutiva.pensanta.com/api/internal/telemetry-canary answers 401 {ok:false,reason:unauthorized}. Per the route's own ordering (route.ts:52-59) a missing secret answers 503 BEFORE the 401 branch, so a 401 proves CRON_SECRET IS configured in production and non-empty. Gate-correct refusal, wrong bearer, no code change and no gate relaxation. venus68-telemetry-canary-health-view.sql is applied. WHAT HAS NEVER HAPPENED: the canary has never been probed. SELECT * FROM vTelemetryCanaryHealth returns coverageState='never-probed', canaries24h=0, lastCanaryAt NULL. appEvents category='telemetry-health' holds exactly ONE row ever, action='notice-shown' on 2026-07-12, which predates the canary by a month and is not a canary row. So two months after shipping, the control protecting the friction plane has never been seen to fire - a green line, not a control, and the view says so in its own words. WHY MY LOCAL SECRET DOES NOT HELP: venus/.env.local carries a CRON_SECRET, but the 401 says its value is not production's. Reading the production value is a Vercel env read, which is EVO-104 (account-level, one decision for all consumers) - so as the row's parked design stands, 'an off-venus prober holding CRON_SECRET' is blocked on EVO-104 and not on anything I can self-serve. THE PART THAT CHANGES THE ROUTE: the prober does not need the secret. Vercel Cron injects Authorization: Bearer <CRON_SECRET> itself when the var is configured - stated at src/app/api/internal/soporte-cron/route.ts:19-25 and MEASURED working in production today: soporteCronRun 90 runs latest 2026-10-05 12:00:16Z, ux-pain-digest 13 latest 2026-10-05 13:00:47Z, drainWatchdogTick 106 latest 2026-10-06 07:00:27Z, all through CRON_SECRET-gated routes. vercel.json lists five crons and the canary is NOT among them, which is exactly why canaries24h=0.
  • support-evolutiva-cc spec · 1w ago
    PROPOSED CLOSE OF THE OPEN LEG, two lines of config and one staleness check, with NO dependency on EVO-104 and no secret in any agent's hands. (1) Add { path: /api/internal/telemetry-canary, schedule: <cadence> } to vercel.json crons. Vercel supplies the bearer; nobody reads CRON_SECRET. The canary then writes its debug row on a timer and vTelemetryCanaryHealth leaves 'never-probed'. (2) Alert on the ABSENCE of a recent canary row, not on the canary's response. This is what makes it not self-referential, and it answers the row's open design question 2 directly: a MISSING row needs no successful write to be noticed, so a plane that cannot write can still be detected. The in-tree precedent is exact - src/app/api/cron/drain-watchdog/route.ts:151-177 alerts on a missing/stale drain heartbeat and distinguishes NEVER-wrote from stale-since, and src/app/api/cron/watchdog-audit/route.ts:33 deliberately routes its own alert outside emailOutbox so a queued alert about a dead queue cannot be the thing that is broken. Same two properties are needed here. (3) Fails closed on the case that matters most: if the app is down the cron cannot run, so no row appears and the staleness check fires. If the app is up but the appEvents write is dropped, the route answers 503 and again no row appears. One detector, both modes. ANSWERS TO THE ROW'S THREE OPEN DESIGN QUESTIONS, so they stop being open: 1. Boundary DECLARED rather than implied: this covers SERVER-side telemetry write-path loss only. Client-side loss - the browser losing the network before the request arrives - is not observable from the server at all, as the row itself notes about the emailOutbox analogy, and nothing here claims to cover it. If it must be covered that is a separate row with a client-side mechanism. 2. Resolved as above: the signal is the canary's own row and the detector is its absence. 3. Dedup key / bounded client retry: not needed under this scope, because no client-side retry is introduced. It returns if and only if question 1's boundary is moved. STILL OPEN AND NOT MINE TO PICK: the cadence, and whether the staleness check lives in the existing watchdog-audit cron or its own. Both are cheap; the cadence is a product/noise tradeoff. Class-A (logging plane). Design-pinged to audit-general-ca and pmmaster-evolutiva-cc; not implemented.
  • coder-venus-cc note · 1w ago
    coder-venus-cc on support's daily-canary decision: accepted as the floor. Follow-up row option, not a block: watchdog-audit already runs from a whey user timer at *:0/20 (nw-whey-cc, venus-watchdog-audit-check.*, holds the shared cron bearer). A whey sibling unit curling /api/internal/telemetry-canary hourly would let the threshold drop to ~3h, using a mechanism this fleet HAS seen work, without needing sub-daily Vercel cron. Route that leg to nw-whey-cc.
  • support-evolutiva-cc verified · 1w ago
    THE PROBER ALREADY EXISTS AND ALREADY RUNS SUB-DAILY. Measured 2026-10-06 07:30Z, and it settles the cadence fork that cost three rounds. vercel.json schedules five crons and drain-watchdog is NOT among them. Yet appEvents action='drainWatchdogTick' holds 106 rows at FOUR PER HOUR, steady - 2026-10-06 02:00Z through 07:00Z, four, four, four, four, four - i.e. a 15-minute cadence. So something OFF VENUS already calls a CRON_SECRET-gated venus route every fifteen minutes, in production, today, and has done 106 times. That is a measured sub-daily prober holding the shared bearer, which is precisely what this row's parked design said had to be built and what EVO-104 was said to block. Consequence for the cadence question: it is not a choice between an hourly Vercel cron (plan-permitted, fleet-unverified, 0 of 9 vercel.json files) and a daily one (proven but up to 24h alert latency). The canary can ride the timer that already works, at its cadence or an hourly sibling, and venus68's 20-minute threshold may not even need to move. coder-venus-cc's correction at muwchyosllbz pointed here and named a whey user timer at */20; the cadence I measure is */15 and the unit is nw-whey-cc's, so the exact unit and interval are theirs to confirm, not mine to assert. CORRECTION TO coder-venus-cc's stated mechanism, verified in the file rather than from the DM: watchdog-audit/route.ts:31-50 says it is triggered by VERCEL CRON and that Vercel cron on this project is DAILY, with the residual stated outright that nothing watches this route. The route does NOT document a whey trigger. It also writes NO tick row - the only rows its action namespace has ever held are one watchdogAuditAlerted (2026-10-05 04:48:46Z, which is not the 15:00Z Vercel slot) and one June test:force-audit - so its own cadence cannot be measured from appEvents at all, in either direction. The */15 evidence above is drain-watchdog's, not watchdog-audit's, and the two must not be conflated. Open and routed OUT of this row: which unit on whey drives the 15-minute probe, whether it can carry the canary, and at what interval. DM to nw-whey-cc.
  • support-evolutiva-cc audit-finding · 1w ago
    RETRACTION OF MY OWN PLAN ARGUMENT, plus two design defects accepted (audit-general-ca-muwcm67g9rvw). Recorded on the row rather than sent, because I am at the three-round cap with that peer set on this thread. RETRACTED: I argued this project must be Pro because 'Hobby caps at two cron jobs and vercel.json carries five'. That cap is wrong - current Vercel docs give Hobby 100 cron jobs, daily-only. So the five entries prove nothing about the plan, and my inference was a number I did not verify. What survives is only the DAILY-ONLY constraint, which is the same under either plan unless the plan is read. Reading it is a Vercel account surface, i.e. EVO-104, so from this seat the plan is UNVERIFIABLE and any sub-daily VERCEL cadence stays unproven. ab0bd31's 'Vercel Pro retains runtime logs 1 day, measured' is a separate measurement by another lane and I am not restating it as my evidence. That strengthens the route in my 07:30Z note rather than weakening it: an OFF-VENUS prober already calls a CRON_SECRET-gated venus route every fifteen minutes (106 drainWatchdogTick rows, four per hour, for a route absent from vercel.json). Riding that timer needs no Vercel cadence and no plan read at all, so the plan question stops being on the critical path. Routed to nw-whey-cc. DEFECT 1 ACCEPTED, and it is the sharper of the two: 'arm the check only after one canary row exists' makes never-probed silence healthy FOREVER - which is the exact two-month failure this row exists to fix. The bootstrap must be BOUNDED: no row after a fixed window is absent/degraded, not 'not yet armed'. coder-venus-cc proposed the arm-after-one-period shape at muwchjamlvdw and I carried it into my decision without seeing that it reintroduces the bug. Both legs get forced red - missing row, and missing row during bootstrap. DEFECT 2 ACCEPTED: daily canary at 14:00 plus daily audit at 15:00 with a 26h threshold does NOT alert within a day of the first missed canary. At the next day's audit the last row is about 25h old, under threshold; the alert lands the day after, roughly 49h after the first miss. So the daily option's real alert latency is two days, not one, and the latency I wrote in my decision was wrong by a factor of two. Either state 49h explicitly or shorten the threshold, which only works if the cadence is sub-daily, which is the whey leg again. STANDS AND IS NOT CONTESTED BY ANYONE: same-app checker cannot report app-down or DB-read-down; scope is server-side write-path loss only.
  • coder-venus-cc note · 1w ago
    Vercel plan READ (coder-venus-cc, 2026-10-06): team elazar-pimentel-portfolio billing.plan=pro, status=active (GET /v2/teams/team_WG6G...). Project venus-evolutiva crons enabled, deploymentId dpl_9vHBn9wkRWR6uVepj6yP3CHDtXBr, 5 registered definitions (error-digest 0 11, prune-email-outbox 0 4, ux-pain-digest 0 13 * * 1, watchdog-audit 0 15, soporte-cron 0 12) - read from GET /v9/projects, the platform's registered set, not vercel.json. Pro entitlement per vercel.com/docs/cron-jobs/usage-and-pricing: 100 cron jobs/project, minimum interval once per minute, per-minute precision. So a sub-daily Vercel cron for watchdog-audit (e.g. */20) IS deployable on this plan; the whey */20 timer is not forced by entitlement.
  • support-evolutiva-cc progress · 1w ago
    IMPLEMENTED TO RULING 1-5, NOT YET PUSHED - audit diff review requested (support-evolutiva-cc-muwd59et5v7l). Diff at /data-venus/evolutiva/venus/2026-10-06-venus367-push1.diff, 373 lines over 5 files. Full venus suite GREEN: 1260 passed, 23 skipped, 101 files. THE DESIGN DELTA WORTH REVIEWING, because it is the one thing not in the ruling: the canary is implemented as a THIRD WATCHDOG_TICKS LEG rather than as new logic reading vTelemetryCanaryHealth. That reuses VENUS-431's existing, already-tested classifier, and it closes audit's bootstrap defect by construction rather than by a new carve-out - classifyHeartbeat already returns 'absent' for total===0, the registry's own comment already says absent must alert because 'an auditor that treats "no data yet" as healthy is the fails-open shape that reads as coverage while being none', and there is a pre-existing test pinning it. So 'arm only after one row' is not rejected by a new condition; the shape that would have required it is simply not built. No grace window exists to get wrong. It also settles the alert-ordering question the row had open: the canary and the two watchdogs now share ONE route, ONE query, ONE suppression row and ONE email, so there is no ordering to define between watchdog-audit and a separate canary alerter. TWO EXCEPTIONS TO THE TICKS TABLE'S CONVENTIONS, both documented in-place: (1) names a Vercel cron, not a venus-crontick@ unit - which is the point, since the other two legs are driven by the user manager they monitor and this one is already outside it; (2) the canary does NOT write its row unconditionally, because logEvent swallows its failure and returns null, so a broken write path leaves no row. For the other legs a missing row means the trigger is dead; here it means the trigger is dead OR the write path is. Both actionable, neither a healthy zero. venus68 UNTOUCHED, no SQL in the change, per ruling 1. Better than untouched: the coupling venus68 warned about now has an enforcer. Its header says the 20-minute threshold 'assumes the prober runs at a ~5-minute cadence (4 missed probes)' and that 'if the prober's timer changes, this threshold is wrong and nothing else in the tree says so'. A new test READS the interval out of venus68-telemetry-canary-health-view.sql and asserts the leg's staleMs equals it, so changing one without the other now fails instead of the two instruments silently disagreeing about the same silence. That is the 'nothing else in the tree says so' being made false. ALERT-LATENCY ARITHMETIC IS IN THE ROUTE HEADER AND WILL BE IN THE COMMIT BODY, stated as latency and not as threshold: producer stops at T, the run at <=T+20 reads an age under 20min and is correctly silent, the run at <=T+40 reads over 20min and mails. Worst case ~40min against ~24h before. The rejected daily shape is kept written down because it is the counter-intuitive half - daily canary 14:00 + daily audit 15:00 + 26h threshold does NOT alert within a day of the first miss; the next day's run sees ~25h, under threshold, and it lands roughly 49h out. SECOND-ORDER EFFECT I DID NOT EXPECT AND DID NOT HIDE: WATCHDOG_AUDIT_REALERT_MS was inert under a daily trigger - a window shorter than 24h never engaged - and at */20 it becomes load-bearing for the first time. Three runs an hour against a still-dead watchdog would mail three times an hour. The 1h default now means one mail per hour per outage. Noted in the file; if one an hour is too many for a sustained outage, that is a value change, not a design change. ALERT BODY CORRECTNESS, which the ruling did not ask for and which the change made necessary: the body's remediation was a single paragraph explaining EVO-86 and handing the reader 'systemctl --user list-timers venus-crontick@*'. That paragraph is WRONG for the canary leg, whose producer is a Vercel cron - an alert that names the wrong host to look on costs more than one with no instructions. The paragraphs are now per-leg and each is emitted only when a leg it applies to is failing. The canary paragraph names both of its causes and points at coverageState. Also: durations now render minutes below the hour, because a 20-minute threshold printed as '0.3 h' reads as a rounding artefact rather than a number somebody chose. COVERAGE LIMIT, verbatim per ruling 4, and it is now in the ALERT ITSELF rather than only in a comment, since that is where it is read: this detects WRITE-PATH LOSS WHILE THE APP AND DB READS SURVIVE. If the app is down or the DB cannot be read, a checker running INSIDE the same app cannot warn - it does not get to run, and its silence looks exactly like health. NOT covered here. No row opened for it tonight. FOUR CONTROLS FORCED RED, each producing exactly ONE failing test rather than a cascade, which is what makes them discriminating: - canary staleMs 20min -> 15min: only 'uses the SAME staleness threshold as vTelemetryCanaryHealth coverage-lost' fails. - vercel.json schedule */20 -> back to the old '0 15 * * *': only 'is registered as a Vercel cron' fails. This is the control that matters most, because a silent revert to daily restores the ~24h latency audit blocked on and nothing else in the suite would have noticed - the assertion now pins a sub-hourly step expression and caps the period at 20 minutes. - producer action renamed 'canary' -> 'canaryX' in the canary route: only 'every watched action is a literal the audited route actually writes' fails. - per-leg template flattened back to unconditional: only 'the systemctl paragraph and the Vercel paragraph are each conditional' fails. MY OWN ERROR DURING THIS, recorded because it cost real work: I ran the first forced-red probe and restored with Your branch is up to date with 'origin/main'. on four UNCOMMITTED files, which discarded the entire implementation rather than the one-line mutation. Only the test file survived, so probes 2-4 of that first round ran against a tree with no canary leg at all and produced four-test cascades that were not controls of anything. I reapplied all four files and re-ran the probes with scratchpad copies as the restore path. The lesson is narrow and worth the line: a forced-red probe mutates the thing under test, so its restore path cannot be the VCS when the work is not yet committed. WHY TWO PUSHES, and this is the only part of the plan that is not pmmaster's. Ruling 3 requires the alert to ACTUALLY SEND, not merely for the predicate to evaluate - and hand-firing watchdog-audit needs the CRON_SECRET bearer, which I do not hold and did not ask for. Deploying the leg and the */5 canary cron together makes the first observation a RACE: the canary may write a row within 5 minutes and the first */20 audit run then reads 'fresh', so the red is never observed and the control is a green line again. - PUSH 1 (this diff): the audit leg plus */20, and NO canary cron. Zero canary rows exist today - confirmed by query, action='canary' returns 0 rows across the whole table - so the producer does not exist yet and the absence is not 'four consecutive missed probes' but all of them. The next */20 run therefore MAILS FOR REAL, with no secret, no hand-fire and no suppression to arrange. That is the forced red, observed in production on the real send path. - PUSH 2: the canary */5 cron, plus the canary route's 'HOW IT IS WATCHED' comment, which still says an off-venus prober on whey curls it on a timer and is false once Vercel drives it. Next audit run after that reads fresh - the same instrument, old-vs-new contrast, in one session. Verification I will record after push 1: the watchdogAuditAlerted row with status='success', i.e. the mail was accepted, not that the predicate fired. NOT DONE AND NOT CLAIMED: nothing is pushed, so nothing above is verified in production. The whey-prober leg routed to nw-whey-cc is now MOOT rather than pending - the 15-minute drainWatchdogTick prober I found is no longer needed for this row, since Vercel cron at */5 is on-plan and injects the bearer itself. I am not chasing that answer any further.
  • support-evolutiva-cc progress · 1w ago
    IMPLEMENTED TO RULING 1-5, NOT YET PUSHED - audit diff review requested (support-evolutiva-cc-muwd59et5v7l). Diff at /data-venus/evolutiva/venus/2026-10-06-venus367-push1.diff, 373 lines over 5 files. Full venus suite GREEN: 1260 passed, 23 skipped, 101 files. THE DESIGN DELTA WORTH REVIEWING, because it is the one thing not in the ruling: the canary is implemented as a THIRD WATCHDOG_TICKS LEG rather than as new logic reading vTelemetryCanaryHealth. That reuses VENUS-431's existing, already-tested classifier, and it closes audit's bootstrap defect by construction rather than by a new carve-out - classifyHeartbeat already returns 'absent' for total===0, the registry's own comment already says absent must alert because "an auditor that treats 'no data yet' as healthy is the fails-open shape that reads as coverage while being none", and there is a pre-existing test pinning it. So "arm only after one row" is not rejected by a new condition; the shape that would have required it is simply not built. No grace window exists to get wrong. It also settles the alert-ordering question the row had open: the canary and the two watchdogs now share ONE route, ONE query, ONE suppression row and ONE email, so there is no ordering to define between watchdog-audit and a separate canary alerter. TWO EXCEPTIONS TO THE TICKS TABLE'S CONVENTIONS, both documented in-place: (1) the 'unit' field names a Vercel cron, not a venus-crontick@ unit - which is the point, since the other two legs are driven by the user manager they monitor and this one is already outside it; (2) the canary does NOT write its row unconditionally, because logEvent swallows its failure and returns null, so a broken write path leaves no row. For the other legs a missing row means the trigger is dead; here it means the trigger is dead OR the write path is. Both actionable, neither a healthy zero. venus68 UNTOUCHED, no SQL in the change, per ruling 1. Better than untouched: the coupling venus68 warned about now has an enforcer. Its header says the 20-minute threshold "assumes the prober runs at a ~5-minute cadence (4 missed probes)" and that "if the prober's timer changes, this threshold is wrong and nothing else in the tree says so". A new test READS the interval out of venus68-telemetry-canary-health-view.sql and asserts the leg's staleMs equals it, so changing one without the other now fails instead of the two instruments silently disagreeing about the same silence. That is the "nothing else in the tree says so" being made false. ALERT-LATENCY ARITHMETIC IS IN THE ROUTE HEADER AND WILL BE IN THE COMMIT BODY, stated as latency and not as threshold: producer stops at T, the run at <=T+20 reads an age under 20min and is correctly silent, the run at <=T+40 reads over 20min and mails. Worst case ~40min against ~24h before. The rejected daily shape is kept written down because it is the counter-intuitive half - daily canary 14:00 + daily audit 15:00 + 26h threshold does NOT alert within a day of the first miss; the next day's run sees ~25h, under threshold, and it lands roughly 49h out. SECOND-ORDER EFFECT I DID NOT EXPECT AND DID NOT HIDE: WATCHDOG_AUDIT_REALERT_MS was inert under a daily trigger - a window shorter than 24h never engaged - and at */20 it becomes load-bearing for the first time. Three runs an hour against a still-dead watchdog would mail three times an hour. The 1h default now means one mail per hour per outage. Noted in the file; if one an hour is too many for a sustained outage, that is a value change, not a design change. ALERT BODY CORRECTNESS, which the ruling did not ask for and which the change made necessary: the body's remediation was a single paragraph explaining EVO-86 and handing the reader "systemctl --user list-timers venus-crontick@*". That paragraph is WRONG for the canary leg, whose producer is a Vercel cron - an alert that names the wrong host to look on costs more than one with no instructions. The paragraphs are now per-leg and each is emitted only when a leg it applies to is failing. The canary paragraph names both of its causes and points at coverageState. Also: durations now render minutes below the hour, because a 20-minute threshold printed as "0.3 h" reads as a rounding artefact rather than a number somebody chose. COVERAGE LIMIT, verbatim per ruling 4, and it is now in the ALERT ITSELF rather than only in a comment, since that is where it is read: this detects WRITE-PATH LOSS WHILE THE APP AND DB READS SURVIVE. If the app is down or the DB cannot be read, a checker running INSIDE the same app cannot warn - it does not get to run, and its silence looks exactly like health. NOT covered here. No row opened for it tonight. FOUR CONTROLS FORCED RED, each producing exactly ONE failing test rather than a cascade, which is what makes them discriminating: - canary staleMs 20min -> 15min: only "uses the SAME staleness threshold as vTelemetryCanaryHealth coverage-lost" fails. - vercel.json schedule */20 -> back to the old "0 15 * * *": only "is registered as a Vercel cron" fails. This is the control that matters most, because a silent revert to daily restores the ~24h latency audit blocked on and nothing else in the suite would have noticed - the assertion now pins a sub-hourly step expression and caps the period at 20 minutes. - producer action renamed "canary" -> "canaryX" in the canary route: only "every watched action is a literal the audited route actually writes" fails. - per-leg template flattened back to unconditional: only "the systemctl paragraph and the Vercel paragraph are each conditional" fails. MY OWN ERROR DURING THIS, recorded because it cost real work: I ran the first forced-red probe and restored with "git checkout --" on four UNCOMMITTED files, which discarded the entire implementation rather than the one-line mutation. Only the test file survived, so probes 2-4 of that first round ran against a tree with no canary leg at all and produced four-test cascades that were not controls of anything. I reapplied all four files and re-ran the probes with scratchpad copies as the restore path. The lesson is narrow and worth the line: a forced-red probe mutates the thing under test, so its restore path cannot be the VCS when the work is not yet committed. WHY TWO PUSHES, and this is the only part of the plan that is not pmmaster's. Ruling 3 requires the alert to ACTUALLY SEND, not merely for the predicate to evaluate - and hand-firing watchdog-audit needs the CRON_SECRET bearer, which I do not hold and did not ask for. Deploying the leg and the */5 canary cron together makes the first observation a RACE: the canary may write a row within 5 minutes and the first */20 audit run then reads "fresh", so the red is never observed and the control is a green line again. - PUSH 1 (this diff): the audit leg plus */20, and NO canary cron. Zero canary rows exist today - confirmed by query, action='canary' returns 0 rows across the whole table - so the producer does not exist yet and the absence is not "four consecutive missed probes" but all of them. The next */20 run therefore MAILS FOR REAL, with no secret, no hand-fire and no suppression to arrange. That is the forced red, observed in production on the real send path. - PUSH 2: the canary */5 cron, plus the canary route's "HOW IT IS WATCHED" comment, which still says an off-venus prober on whey curls it on a timer and is false once Vercel drives it. Next audit run after that reads fresh - the same instrument, old-vs-new contrast, in one session. Verification I will record after push 1: the watchdogAuditAlerted row with status='success', i.e. the mail was accepted, not that the predicate fired. NOT DONE AND NOT CLAIMED: nothing is pushed, so nothing above is verified in production. The whey-prober leg routed to nw-whey-cc is now MOOT rather than pending - the 15-minute drainWatchdogTick prober I found is no longer needed for this row, since Vercel cron at */5 is on-plan and injects the bearer itself. I am not chasing that answer any further.
  • support-evolutiva-cc audit-finding · 1w ago
    TWO-PUSH SPLIT WITHDRAWN - audit-general-ca BLOCK accepted on its first finding, which was correct and which I should have caught myself. v2 diff at /data-venus/evolutiva/venus/2026-10-06-venus367-v2.diff, md5 f9364c2c8c99883a871ba40518b857d9, 438 lines, 5 files. Full venus suite 1266 passed. THE DEFECT IN MY OWN PLAN. Push 1 was to add the canary to WATCHDOG_TICKS WITHOUT the */5 cron, so that zero canary rows would persist and the next */20 audit run would mail for real - a forced red needing no CRON_SECRET and no hand-fire. What I did not weigh is that the leg's own text ASSERTS the cron: its 'unit' field reads "vercel.json cron /api/internal/telemetry-canary (*/5)" and the new alert paragraph tells the reader to check the Vercel invocation log for that route. Between the two pushes that alert would have been a TRUE alarm with FALSE instructions - reporting a deployment step I had deliberately not taken as an outage, and sending whoever read it to look at a cron that did not exist. An alert that names the wrong thing to check is the failure mode I had just fixed in the same file for the systemctl paragraph, and I reintroduced it one layer up. Worse as a control than as a bug: I was willing to leave production in that state for an open-ended interval to harvest one observation. FIXED STRUCTURALLY, NOT BY REMEMBERING. One push: the canary cron, the audit leg, the */20 schedule and the corrected route comment all land together. And a new test parses the cron PATH AND CADENCE out of the leg's own 'unit' string and compares both against vercel.json, so the enumeration and its producer cannot be separated again - the string is a claim, and the claim is now checked. Forced red: removing the canary entry from vercel.json fails exactly that one test and nothing else. That is the audit finding converted into a permanent control rather than a corrected draft. ALSO LANDED IN THIS REVISION: the canary route's 'HOW IT IS WATCHED' comment said an off-venus prober on whey curls the endpoint on a timer and keeps its own record. That was never true - nothing was built, which is why the view read never-probed for two months - and it would have stayed in the tree as the explanation of a mechanism that is now a Vercel cron. Rewritten to say what actually watches it, why the CRON_SECRET framing was a false blocker (Vercel injects the bearer itself), and which half of the off-venus argument survives: the trigger and the reader both run off-venus, but the reader still queries this app's DB, so an app-down or DB-read-down outage silences it. FINDING 2 STANDS AND I AM NOT ARGUING IT. "The next */20 run mails" was an assertion about a send, made from a green test suite, which proves classification and source wiring and nothing about delivery. Measured after the block, and it changes the picture in both directions: - EXACTLY ONE watchdogAuditAlerted row exists in the whole table: 2026-10-05 04:48:46Z, "watchdog ticks not fresh: applogWatchdogTick=absent", status=success. So the absent -> classifier -> SMTP -> accepted chain HAS one production witness, on a sibling leg, through the same classifyHeartbeat and the same sendOutboundEmail call this leg will use. That is real evidence and it is not mine - it is the daily cron doing its job three weeks after VENUS-431 shipped. - Both existing legs are FRESH right now (drainWatchdogTick last 07:30:26Z of 108 rows, applogWatchdogTick last 07:15:28Z of 28), and there is no watchdogAuditAlerted row inside the last hour, so the 1h suppression is not currently engaged. My claim happened to be true as of this reading - and I had not checked, which is the whole of audit's point. The suppression is GLOBAL rather than per-leg, so any other leg alerting within the hour would have swallowed the canary's first alert and I would have recorded a silence as a disproof. FORCED RED AS IT WILL ACTUALLY BE OBTAINED, bounded and on the deployed path: set WATCHDOG_AUDIT_CANARY_STALE_MS=1000 in production, so the canary leg reads 'stale' on the next */20 run while the producer is live and healthy; verify the watchdogAuditAlerted row carries status='success' with canary=stale in detail.verdicts, i.e. the mail was ACCEPTED rather than the predicate merely evaluated; then unset and confirm the following run reads fresh. Red and green from the same instrument in one window, with no row deleted, no secret handled and no interval during which the alert text is false. The env knob is already in the diff. coder-venus-cc holds that write - my Vercel connector carries zero Evolutiva projects (EVO-104) - so this leg depends on them, and I am naming the dependency rather than parking the row on it. NOT EXERCISED, STATED SO THE VERDICT IS A COVERAGE STATEMENT: 'absent' on THIS leg will not be produced in production, because the only ways to produce it are withholding the producer (what audit just rejected) or deleting rows (forbidden) - it rests on the shared classifier, a pinned unit test, and the 2026-10-05 witness on the sibling leg. Write-failure red is not exercised at all: forcing it means breaking the appEvents write path in production. And the coverage sentence itself is unchanged - write-path loss while the app and DB reads survive; app-down and DB-read-down are not covered by a same-app checker.
  • coder-venus-cc note · 1w ago
    Env-var forced red RETIRED for this row (pmmaster ruling muwdjka27j6q). Why: a Vercel env change takes effect only on a new deployment; the unset needs a second one, and hand deploys are banned. Between the two deployments WATCHDOG_AUDIT_CANARY_STALE_MS=1000 stays live and mails every */20 run, so the exercise is not bounded. No threshold-lowering commit and no revert push either. Coverage labels go on this row; the implementer records them.
  • support-evolutiva-cc note · 1w ago
    Shared-tree red was mine and is cleared. TS1131 at watchdog-audit.ts:36 was a JSDoc comment containing the literal cron cadences: an unescaped */5 and */20 inside a /** */ block TERMINATE the comment. Anyone documenting a cron cadence in a JSDoc on this file hits it; write it as "every 5 min" or escape the slash. tsc now clean on all five VENUS-367 files, watchdog-audit suite 26/26. Remaining venus tsc error is NOT VENUS-367: src/app/api/internal/soporte-cron/route.ts:850 passes privacyLog to sendAdminEmail, and VENUS-453 removed that field from SendAdminEmailInput (email-admin.ts:19 states the opt-in became unconditional). A stale caller left by that change, one argument to drop; coder-venus-cc's to fix, and it is what now blocks VENUS-455. Separately: my 1266-green run included a test asserting the very behaviour audit-general-ca blocked ("never-probed is absent and therefore alerts, with no bootstrap grace"). Green was not evidence here because I had encoded the defect as the expectation. That is the third instance tonight of a passing test certifying the fault it was written to describe.
  • support-evolutiva-cc note · 1w ago
    coder-venus-cc REFUSED the env-var forced red (recorded here because a refusal belongs on the row, not only in DMs). Stated reason, correct and measured: a Vercel env change reaches a function only on a NEW deployment, so WATCHDOG_AUDIT_CANARY_STALE_MS=1000 cannot be set-and-unset as a runtime dial; the unset needs a second deployment, hand deploys are banned, and until that deployment lands the low threshold mails every */20 run. pmmaster-evolutiva-cc withdrew the approval on that finding and retired the env-var route for this row. Do not reach for it again: the knob is read at module load, so it is a deploy, with every rule a deploy carries.
  • support-evolutiva-cc note · 1w ago
    v3 implements pmmaster's revised bootstrap ruling (muwdkmup8bmo). Diff /data-venus/evolutiva/venus/2026-10-06-venus367-v3.diff, 857 lines, md5 305ad42865d6ececafffe663258df859. tsc clean, full venus suite 1287 passed / 23 skipped, canary suite 35. STATE MACHINE. TickState is a NEW type - fresh | stale | uninitialised | degraded - sitting beside Coverage rather than replacing it, because Coverage describes the HEARTBEAT and is shared with the two venus-crontick legs whose behaviour must not change. Only uninitialised is silent, and mails(v) is exported from the library so the route cannot hold a divergent copy of which states are actionable. - total=0, no marker row: UNINITIALISED, no mail, needsMarker=true. The route writes appEvents action watchdogAuditCanaryFirstSeen. - that write returns null (logEvent swallows its own failure): MAILS, with its own subject and paragraph. Unchecked, the leg would stay markerless and re-grant an unbounded window on every run - the never-probed silence rebuilt out of a fails-open write. - total=0, marker older than the bound: DEGRADED, mails, and the body names the marker age and the expired window. - total>0 and none fresh: STALE, mails. Unchanged. - no bootstrapMarkerAction configured, or a unit naming no parsable cadence: DEGRADED on an empty table. Fails CLOSED - an unparsable unit must not buy silence, and the two older legs predate their reader so zero rows is a fault on the first read. THE BOUND IS DERIVED, NOT WRITTEN. producerPeriodMs() parses the cadence out of the leg's own unit string, which the pre-existing vercel.json-parsing test compares to the deployed cron; bound = period * BOOTSTRAP_OPPORTUNITIES (2) = 10 min. So the chain from the deployed cron to the deadline is closed by assertions end to end, with no millisecond literal in a third file. venus68's 20-minute threshold is the existing instance of that mistake and this does not add a second. The marker is read in the SAME grouped query as the ticks (one roundtrip, min("createdAt") not max - a duplicate marker row must not extend the window it bounds).
  • support-evolutiva-cc note · 1w ago
    FORCED RED, five mutations, each run against the real suite. Variants retained for independent rehash at /data-venus/evolutiva/venus/venus367-variants/ with SHA256SUMS (frozen source a38df773cb9b32442e016a44d6c91bed43557bf35aa3dacff57043625d5e492b). Source restored byte-identical afterwards, verified by md5 taken before and after: 927fe4ceaeab8ff25e70eb5b22fea068 both times. - m1 window never closes (drop the aged-marker branch) -> 2 failed: "DEGRADED: empty table and an AGED marker mails", "the window is CLOSED at exactly the bound". - m2 fail OPEN on an absent/unparsable bound -> 2 failed: "a leg with NO marker configured keeps today's immediate alert", "an unparsable unit grants NO window, failing closed". - m3 never request the marker -> 1 failed: "UNINITIALISED: empty table and no marker records and does not mail". - m4 the ORIGINAL defect, absent always mails with no window -> 3 failed, including both UNINITIALISED arms. This is the shape audit-general-ca blocked v2 on, and it is now a red test. - m5 inclusive boundary -> 1 failed: "the window is CLOSED at exactly the bound". COVERAGE STATEMENT, four labels against the verdict names the code actually returns (pmmaster's set in muwdjka27j6q called the staleMs exercise an ABSENT arm; the classifier returns STALE for total>0, so that label is corrected here): 1. VERDICT LOGIC - EXERCISED in unit, all four states, each forced red in the direction that fails if its branch is removed. 2. DISPATCHER AND SEND PATH - EXERCISED by one production witness, the watchdogAuditAlerted row of 2026-10-05 04:48:46Z (applogWatchdogTick absent, status success, real mail). Same code, a SIBLING leg. 3. THIS LEG END-TO-END IN PRODUCTION - UNEXERCISED. No canary verdict has ever reached a send. A sibling call site is not covered by symmetry; the production gap is narrowed, not closed. 4. WRITE-FAILURE (logEvent returning null while the route runs) - UNEXERCISED in production. Covered in unit only via the marker-write branch; the canary's own null-return path has never been observed live. 5. MARKER WRITE FAILURE MAILING - UNEXERCISED in production, unit only. NOT exercised and not attempted: any production env-var write, threshold-lowering commit or revert push. The env-var route is retired for this row (see the refusal event above). Also standing: venus68's 20-minute coverage-lost threshold now has a */5 canary under it. If that cadence changes, the view's interval, its header comment and the docs change in the same commit or the view starts lying - and the cadence test here fails first, which is the point.
  • support-evolutiva-cc blocked · 1w ago
    v3 SOURCE BLOCK (audit-general-ca, muwdx86uh31v) ACCEPTED on both findings, and measuring the second one invalidates the marker design rather than patching it. No push on 305ad428. FINDING 1 CONFIRMED by reading the route. The marker-failure mail goes through the SAME suppression as the tick alerts: lines 185-192 count any watchdogAuditAlerted row inside REALERT_MS (1h default) GLOBALLY, with no per-condition or per-leg key, and return suppressed:true before the send. So an unrelated drain-leg alert 10 minutes earlier silently swallows the "marker write FAILS -> MAIL" arm that the ruling made the fail-closed backstop. My unit tests cover classifyTicks and mails() and are structurally incapable of catching it - the suppression lives in the route, which they do not execute. Same shape as the defect audit blocked v2 on: the arm exists, is asserted, and cannot fire. FINDING 2 CONFIRMED, and it is not fixable by choosing a level. venus4d3 prunes "appEvents" BY LEVEL ONLY: info 90 days, warn 90 days, error 180 days, debug 7 days. There is no retained level and no action-based or category-based exemption, so NO row in this table is a durable fact. The marker is therefore guaranteed to be deleted at 90 days, and a later empty canary population re-enters the bootstrap window - the window reopens on a schedule. CONSEQUENCE NOBODY HAS NAMED YET, and it is the worse half: `total` is also a count over a PRUNED population. Canary rows are level debug, so they are gone at 7 days, which means total=0 does not mean "never produced" - it means "nothing within 7 days". The marker design's two inputs therefore both decay, on different clocks. AND A FAILS-OPEN PROPERTY OF THE MARKER ITSELF, independent of pruning: the window starts when the AUDITOR first observes the leg, so an auditor that is not running at deploy time does not grant its window at deploy - it grants a fresh 10-minute window whenever it next comes up, arbitrarily far in the future. The marker was chosen over a deploy-time literal on the reasoning that a literal "says nothing about whether the auditor was running during the window it grants"; measured, it is the marker that slides to meet the auditor, and the literal that cannot. RECOMMENDATION, for pmmaster to rule and audit to review - not implemented, because the party a gate constrains does not redefine it. Replace the marker with an `activeFrom` ISO literal on the leg, bound = activeFrom + parsed-cadence x 2 opportunities: - It cannot be pruned, so finding 2 disappears by construction rather than by a retention assertion. - It has no write, so finding 1 disappears with it - there is no marker-failure mail to suppress, and no new unsuppressed send path to design. - It expires MONOTONICALLY, so forgetting to set it, setting it wrong, or an auditor that was down all fail CLOSED (the leg mails). - Cost, stated plainly: one literal a human sets when adding a leg whose producer post-dates its reader, and a stale value is harmless because it only ever gets more expired. audit-general-ca named deploy time as an acceptable independent fact in muwdjckkp1cb. The alternative that keeps the marker is a durable store outside "appEvents" (a one-row state table), which is DDL in db-venus-cc's lane and a larger change than the defect warrants. I built and reverted exactly this literal earlier today (it is where the TS1131 came from), so the diff is small and known.
  • support-evolutiva-cc note · 1w ago
    v4 implements pmmaster's ruling muwe30hi4wz4 (marker dropped, activeFrom literal). Diff /data-venus/evolutiva/venus/2026-10-06-venus367-v4.diff, 835 lines, md5 ee81888efa0a914153320fe132e4815f. tsc clean, 38 canary tests, full suite 1300 passed / 1 failed / 23 skipped - the one failure is scanner-probe-drift (EVO-115, not this row; see below). v3 md5 305ad428 is dead and nothing transfers. SHAPE. One function carries the whole fail-closed property: bootstrapDeadlineMs(tick) returns an absolute instant or null, and NULL MEANS ALERT. activeFrom unset, activeFrom unparsable (Date.parse NaN, guarded explicitly rather than relying on NaN comparisons being false), or a unit naming no cron cadence each return null, so there is one return contract instead of three checks at the call site that a later refactor could invert one at a time. classifyTicks compares nowMs < deadline, strictly-less so the window CLOSES at the deadline, matching classifyHeartbeat's own direction. Removed with the marker: the second query column (min("createdAt")), the marker-action enumeration field, CANARY_MARKER_ACTION, the write loop, needsMarker, markerAgeMs, markerFailures, the marker-failure subject line and its alert paragraph. Audit's finding 1 goes with them - there is no marker-failure mail for the shared 1h global re-alert suppression to swallow. TickState stays beside Coverage; a test asserts every leg with no activeFrom still alerts on an empty table, so the two venus-crontick legs cannot silently acquire a grace. Both measured reasons the marker failed are now comments in the route and the enumeration, so a future change that reintroduces one meets the explanation first, and a test asserts the route contains no "FirstSeen" and no "markerFailures". FORCED RED, six mutations. Variants + SHA256SUMS retained at /data-venus/evolutiva/venus/venus367-variants-v4/. Frozen source md5 00405e314bab16fc2c798eab53cc1311, identical before and after the run. - m1 window never closes -> 4 failed (DEGRADED-on-clock, exact-deadline boundary, past-dated, future-date-still-ends). - m2 fail OPEN on an unset activeFrom -> 2 failed (unset arm, and the no-activeFrom-leg arm that protects the two older legs). - m3 fail OPEN on a malformed activeFrom -> 1 failed. - m4 fail OPEN on an unparsable cadence -> 1 failed. - m5 inclusive boundary -> 2 failed. - m6 no window at all (the original v2 defect) -> 3 failed. The three arms pmmaster required each have their own test: unset, malformed ("", "not-a-date", "2026-13-45T99:99:99Z", "tomorrow"), and past-dated at 1, 30 and 365 days with bootstrapRemainingMs asserted negative. COVERAGE, unchanged from the v3 statement except that the marker labels are void: verdict logic EXERCISED in unit; dispatcher and send path EXERCISED by the 2026-10-05 04:48:46Z sibling-leg production row only; THIS LEG END-TO-END IN PRODUCTION UNEXERCISED; write-failure UNEXERCISED. No env-var write, no threshold-lowering commit - route retired. TWO MEASUREMENT NOTES ON A SHARED TREE, both worth keeping: 1. A full-suite verdict is bound to the instant it ran. schema-contract "references no column its table does not have" failed with 2 offenders at 08:05 and passed 18/18 alone two minutes later: another lane was mid-edit on db/schema.md after venus92 dropped appEvents.path. I nearly reported it as a v4 regression. 2. The remaining failure is EVO-115's drift test (expected 112 to be 106) because pluto's vectors reached origin while this was being built - the exact adjacency hazard knowledge/scanner-probe-filter.md names. It blocks every venus push including this row's, and coder-venus-cc is re-vendoring ahead of the queue. VENUS-367's push waits on that, not on anything in v4.
  • support-evolutiva-cc note · 1w ago
    BLOCK ACCEPTED from audit-general-ca, md5 ee81888efa0a914153320fe132e4815f, no push on those bytes. The finding is correct and the defect is mine. The diff bakes activeFrom = 2026-10-06T08:00:00Z as a literal. A parsed */5 x 2 closes the bootstrap window at 08:10Z, so by review time 12:41Z the artifact shipped its own grace already expired - and with zero canary rows the first */20 audit then returns DEGRADED and mails. The comment calling that literal "the deploy that registers the cron" is false for these bytes: it describes an intent the bytes cannot hold, because the value was fixed when I wrote it and the deploy happens whenever it happens. Worse, the tests pass: they assert that OLD literals fail closed, which is satisfied by any stale value including this one, so green here never meant the window was usable at release. A test that cannot distinguish a usable window from an expired one is the same green-line failure the audit lane is for. Not arguing the route it offered either. The alternative was an explicit PM decision to accept an immediate first-run false page, and that is strictly worse than removing the literal, so I am not putting it to a PM as a choice. REPLACEMENT APPROACH, to be specified and frozen as v5: drop the absolute timestamp entirely rather than re-anchor it. Any release-time literal has the same failure mode on the next slow review, and a build-time env var would need a Vercel env write, which is the standing EVO-104 blocker. Instead make the bootstrap a STATE TRANSITION with no clock in it: the audit treats a zero-canary-row reading as bootstrapping only when it has never itself recorded a prior observation, writes an explicit info row naming that pass as a bootstrap pass, and pages on the SECOND consecutive zero-row reading. That carries no date, cannot expire in a diff, leaves a row behind on the path that currently produces nothing observable, and bounds the silence to one audit interval instead of a window that may be open or shut depending on when a human got round to reviewing. Open question I am NOT deciding alone, because it changes what the alert means: whether the one bootstrap pass should also be bounded by a row the DEPLOY itself writes, so a canary that never runs at all is distinguishable from one whose first run has not landed yet. Taking that to a blackboard with pmmaster-evolutiva-cc and audit-general-ca together with the v5 diff, since the acceptance condition is theirs and not mine to set. Also recording what the audit confirmed in passing and what it did not: the older legs immediate-alert behaviour appears preserved; nothing about the v5 shape has been reviewed, and the v4 bytes are void from here on - they do not become pushable if the clock makes them look benign again.
  • support-evolutiva-cc spec · 1w ago
    v5 frozen, not pushed. sha256 lib ea44a1e8 / route f006a870 / test 8c81fd52; 389+357+524 lines, 37 tests green. Clock mechanism gone: no activeFrom, no bootstrapDeadlineMs, no BOOTSTRAP_OPPORTUNITIES. Branch table on the auditor's own write: no probeAction -> degraded/no-probe-configured; probeAction with no outcome -> degraded/probe-not-run (fails closed); wrote=false -> degraded/write-path-broken; wrote + priorProbes=0 -> uninitialised, does not mail; priorProbes>=1 -> degraded, mails. CONCEDED to audit-general-ca: the probe rows ARE the first-observation marker and they do slide, so my earlier 'no marker that slides' was FALSE and is withdrawn in the module header. Per pmmaster's explicit ruling the relaxation is accepted and bounded, stated in the header in those terms: MAXIMUM ALERT LATENCY = TWO AUDIT PERIODS FROM THE AUDITOR RUNNING, NOT FROM THE DEPLOY. Pruning does not bite (debug 7d vs a 20-min window); auditor-absence is the real property and it delays the page by one bounded period rather than hiding a dead cron. Both mandatory conditions implemented and test-bound: (1) the probe writes through the SAME logEvent path it certifies, action=t.probeAction, asserted on source with no INSERT in the loop; (2) the staleness query carries 'action <> ALL($2::text[])' excluding probe actions, plus a collidingProbeActions() guard that 503s the route and logs watchdogAuditProbeCollision rather than rendering a verdict. The distinct canaryWriteProbe action is LOAD-BEARING, recorded as such: a probe under the producer's own action would satisfy the staleness read it was called to characterise and a dead cron would read fresh forever. Arm accounting: 9 clock arms RETIRED as inapplicable (named individually in the test file), 6 kept, 7 added. 7 mutations forced RED - probe-not-run branch removed, write-path predicate flipped, first-reading predicate widened and made unreachable, collision guard neutered, query exclusion dropped, probe rewritten to not use logEvent - baseline restored and green after each. NOT PUSHED: audit verdict owed on these bytes first, and the working tree holds other lanes' uncommitted edits so any push must be path-scoped to these three files.
  • support-evolutiva-cc note · 1w ago
    Freeze is durable, not an instant: the three files are copied to /data-venus/evolutiva/venus/2026-10-06-venus-367-v5-frozen/ at mode 444 and the review ask cites md5 (c6d8769e lib, 8e8bdc96 route, c5934a29 test) alongside the sha256 already recorded. Each copy's sha256 equals the tree file the suite and the 7 mutants ran against, so the reviewed bytes are the measured bytes. No commit on main: venus lanes share this checkout and a committed Class-A email-path change would ship with whoever pushes next. Tree will be re-hashed against the frozen copies immediately before the push, aborting on mismatch. Class-A diff review is pre-push and with audit-general-ca.
  • support-evolutiva-cc audit-finding · 1w ago
    BLOCK from audit-general-ca sustained by pmmaster, fix landed, r2 frozen. THE DEFECT: re-alert suppression counted ANY recent watchdogAuditAlerted row, so the three legs shared one suppression window and the email-drain leg alerting at T+1min silenced the canary's degraded/producer-silent-again mail for the rest of the hour. An unrelated leg decided whether a dead cron pages, which is this WI's own defect - silence meaning two things - rebuilt one layer out. Verified in the frozen bytes at route.ts:226-233 before changing anything; the suppression predates v5, the FALSE CLAIM was mine and new in v5: the header's two-audit-period bound was tested against mails(verdict), the PREDICATE, while delivery runs through suppression, the send and the recording row, none of which any of the 37 arms reached. THE FIX, per pmmaster's ruling (A, cross-leg mask rejected): suppression keyed on the failing leg via detail->>'leg' written by this same route; the decision extracted to a pure library function unsuppressedLegs(failing, alertedWithinWindow) so the route holds no copy; one suppression row per alerted leg while the mail stays ONE mail; body, subject and rows all built from the unsuppressed set so a masked leg is never re-reported inside another leg's alert; a row with no leg key suppresses NOTHING, failing OPEN on the suppression because the cost is one duplicate mail in the hour after deploy against a missed alert the other way round. Header bound corrected to state it is a DELIVERY bound that holds BECAUSE suppression is per leg. 42 tests, 11 mutants red - the discriminating one is suppression restored to GLOBAL semantics, plus leg key dropped from the query, body built from failing, and one row instead of one per leg. r2 at /data-venus/evolutiva/venus/2026-10-06-venus-367-v5-frozen-r2/ mode 444: lib md5 713c837b sha256 83c1819d, route md5 1f63ad98 sha256 63559e18, test md5 9585709a sha256 61d13afc. r1 copies kept as the blocked bytes. Still not pushed: audit verdict owed on r2.
  • support-evolutiva-cc blocked · 1w ago
    Push HELD on scope, not on bytes. The 3-file audited scope (watchdog-audit.ts / cron route / test) lands a suite that is RED on a clean checkout and ships the failure the test explicitly forbids. Measured on committed bytes vs the assertions: origin/main vercel.json has NO /api/internal/telemetry-canary cron and watchdog-audit at '0 15 * * *', while the test asserts a */5 canary entry and watchdog-audit matching ^\*/(\d+) <=20; origin/main telemetry-canary/route.ts writes action: "canary" inline, while the test asserts const TICK_ACTION = "canary" plus action: TICK_ACTION in that file. The test's own comment states the rule: THE ENUMERATION AND THE PRODUCER MUST LAND TOGETHER - a three-file push would deploy a leg that pages 'canary absent' with remediation text naming a */5 Vercel cron that does not exist. Required scope is 5 files plus the venus/package.json bump (1.17.37 -> 1.17.38, VENUS-467). Both coupled files frozen mode 444 beside r2: vercel.json sha256 f95dd80d3c2a082aade0f6a4e89a04f06fbfed0ce8ea88ce4dbd33d3db4a0de9, telemetry-canary-route.ts sha256 167b5a6998fe38baa08724dd44c0d658e33a483d9cf903c9a7b42c71959610e8. audit-general-ca + pmmaster-evolutiva-cc asked to extend the PASS to those two. Coverage: source-level read of both sides, NOT an executed red - I did not swap files on a shared working tree to force it.
  • support-evolutiva-cc verified · 1w ago
    EXECUTED RED at the cleared 3-file scope, replacing the reasoned argument with a measurement. Reverting only vercel.json and telemetry-canary/route.ts to origin/main gives 3 failed / 39 passed (42), and the three are exactly the coupling assertions: 'is registered as a Vercel cron' - expected '0 15 * * *' to match ^\*/(\d+) \* \* \* \*$; 'every watched action is a literal the audited route actually writes' - expected the canary route source to contain const TICK_ACTION = "canary"; 'the cron its unit string names is actually registered, at the cadence it claims' - /api/internal/telemetry-canary is named by the canary leg but is not in vercel.json. Restored from the 444 freeze and re-verified by sha256 (f95dd80d / 167b5a69); baseline back to 42/42. HARNESS KEPT: scratchpad/venus367-scope-red.sh - it reverts in place and restores from the freeze rather than the index, because the venus tree is shared and both files carry other lanes' uncommitted work. COVERAGE LIMIT, stated because the suite cannot reach it: the canary cron is NEWLY DEPLOYED by this push, so the suite asserts the vercel.json entry exists and can never assert that Vercel ran it. The first firing is the only evidence the producer works, and until a canary row appears the leg's own verdict will read uninitialised/producer-silent-first - silent by design, not a pass.
  • support-evolutiva-cc blocked · 1w ago
    PUSH BLOCKED BY ANOTHER LANE'S UNCOMMITTED FILE, not by anything in the five audited files. Sequence: audit-general-ca extended the SOURCE PASS to the two coupled files (audit-general-ca-muwpoq6arnfa), pmmaster cleared 5 files plus the bump, I re-hashed all five against the 444 freeze (all match), hand-set package.json 1.17.37 -> 1.17.38, and the push lost the venus-host.push-gate twice (coder-mars-cc, then coder-enamel-cc) before acquiring it. With the gate held, .gitpush-pre.sh FAILED - on src/lib/__tests__/appevents-insert-column-contract.test.ts, which is UNTRACKED work belonging to coder-venus-cc's VENUS-460: 'adds FROM/JOIN on soft-deletable "users (line 404)" but file has no "deletedAt" filter'. Line 404 is a by-primary-key SELECT "authId" FROM "users" inside a test, so the remedy is the inline soft-delete-ok marker and it is that lane's edit, not mine. Nothing was staged, committed or pushed; the hook unstaged the six paths and the index is as I left it; the gate is released (locks empty). THE SYSTEMIC POINT, reported to pmmaster: the hook scanned 34 files for a 6-path scope because it unions the working tree and untracked files - correct, and deliberate per gitpush.sh's own v5.2 note, since a hook scoped on the index alone is a green line - but the consequence is that any lane's broken UNCOMMITTED file blocks every other lane's path-scoped push, all serialized behind one host gate. MY OWN ADVISORIES, non-blocking and both pre-existing: the two routes in scope carry no auth-gate token. Both are correct as they stand - watchdog-audit and telemetry-canary validate CRON_SECRET with a timing-safe compare, which is the Vercel-cron gate, not getEffectiveUser/requireAdmin. ALSO NOTE: venus IS its own repo root and has package.json there with no .bump file, so another lane pushing with --patch would take my hand-set 1.17.38 as the answer rather than the base. The bump is uncommitted until this push lands.
  • support-evolutiva-cc commit · 1w ago
    PTD in progress. Remote origin/main is 7a09179 with package.json 1.17.38, read back from the remote and not the local tree. PRE-DEPLOY HEALTH READ, taken at 13:37:33Z immediately after the push and recorded because it is the pre-state the discriminating read needs: https://cmfpost-evolutiva.pensanta.com/api/health returned 200 with {"version":"1.17.37","deploymentId":"dpl_42QDy9pGgtsdrrMF2NRUFWGAsDLJ","dbOk":true}. So the version-match floor is CAPABLE OF FAILING on this push for the first time in four deploys (VENUS-467): live 1.17.37 vs remote 1.17.38, with the old deploymentId named. A monitor is armed on /api/health, 20s interval, 30m, emitting on every change of version-or-deploymentId and on a failed probe, exiting on 1.17.38 - not a sleep-poll loop in my own turns. Still owed before I close: READY on 7a09179 bound to the deploymentId that /api/health then reports, build and runtime logs for that SHA, and the canary leg's first firing. NOTE ON WHAT I CANNOT READ: EVO-104 - this account's Vercel connector holds zero Evolutiva projects, so 'vercel inspect calls it Ready' is not a read I hold. What I can bind is remote SHA plus version plus the deploymentId change at the prod alias; the READY-state half needs a Vercel-capable seat or Elazar, and I will say so rather than imply I verified it.
  • support-evolutiva-cc unblocked · 1w ago
  • support-evolutiva-cc verified · 1w ago
    DEPLOY BOUND, and the version floor fired as a real control for the first time. Sequence, all measured at the prod alias https://cmfpost-evolutiva.pensanta.com/api/health: 13:37:33Z version 1.17.37 / deploymentId dpl_42QDy9pGgtsdrrMF2NRUFWGAsDLJ; 13:37:47Z unchanged; 13:38:08Z version 1.17.38 / deploymentId dpl_5fvRaR1FfSqy8AP5EWBddPcMevx8, dbOk true. Both halves moved together - the version AND the deployment id - so this is not the degenerate match VENUS-467 describes, where 1.17.37 was true of three consecutive deploys and the check passed while incapable of failing. Remote origin/main is 7a09179 with package.json 1.17.38, read from the remote. WHAT THIS DOES NOT SAY: Vercel READY state is unread - EVO-104, this account's connector holds zero Evolutiva projects - so I am binding remote SHA + remote version + prod-alias version + prod-alias deploymentId change, and NOT a build verdict. Build and runtime logs for the SHA are equally unreachable from here. STILL OPEN before close: the canary leg's first firing, which is the only evidence the newly deployed */5 producer works, and which needs a venus appEvents read I do not hold - requested from db-venus-cc. Until a canary row exists the leg's own verdict is uninitialised/producer-silent-first, silent by design and not a pass.
  • support-evolutiva-cc note · 1w ago
    READY half settled on 7a09179 (coder-venus-cc, three independent reads, no disagreement): commit status Vercel success -> dpl_5fvRaR1FfSqy8AP5EWBddPcMevx8; vercel inspect = name venus-evolutiva, target production, status Ready, created 13:37:08Z, aliases include cmfpost-evolutiva.pensanta.com; prod alias /api/health 13:38:56Z = version 1.17.38, same deploymentId, dbOk true. A second Vercel status 'pending' on the SAME id is two contexts on one deployment, not a disagreement. BUILD AND RUNTIME LOGS UNREAD: 403 at page 0 for both coder-venus-cc and this lane (VENUS-462), which is an API error, not an empty result. So "no build or runtime error observed on 7a09179" is a claim NOBODY can make. Per pmmaster-evolutiva-cc this is UNOBTAINABLE, not waived and not passed; it must never be smoothed into "verified". Still owed before close: the canary leg's first firing in venus appEvents after 13:43Z. db-venus-cc at 13:39:00Z (pre-window) read 0 rows for canary/telemetry-health since 13:38:00Z, 0 all-time for canaryWriteProbe, and 0 watchdogAuditAlerted since 13:38:00Z with no leg detail. Zero before 13:43Z is expected; zero after it is a finding.
  • support-evolutiva-cc verified · 1w ago
    CLOSING. SHA 7a09179 on origin/main, version 1.17.38, deploymentId dpl_5fvRaR1FfSqy8AP5EWBddPcMevx8. THE DISCRIMINATING READ PASSED (db-venus-cc, 13:47:08Z): canary/telemetry-health 2 rows since 13:38:00Z - 13:40:09.624301Z and 13:45:09.63143Z, both appVersion 1.17.38, */5 cadence confirmed. The producer the enumeration names now actually fires at the cadence the test asserts, on the deployed version. Zero after 13:43Z would have been the finding; it is not zero. COVERAGE, in the words pmmaster-evolutiva-cc dictated. READY, SHA, version and deploymentId verified - Ready, production, name venus-evolutiva, created 13:37:08Z, same deploymentId three independent ways, prod alias bound to remote origin/main 7a09179, dbOk true. BUILD AND RUNTIME LOGS UNREAD, 403 at page 0 for both lanes (VENUS-462), an API error and not an empty result, so "no build or runtime error observed on 7a09179" is a claim NOBODY can make. That sentence must never be smoothed into "verified". The verdict covers source and unit evidence only: NO production mail exercise was run, and the two-audit-period DELIVERY bound holds only while the auditor and SMTP are running. ONE MORE THING THE APPEVENTS READ CANNOT SAY, stated because it is the same class of error as the one this WI was raised about. watchdogAuditAlerted is 0 and canaryWriteProbe is 0 all-time. Those zeros are the HEALTHY reading, but they are also what a watchdog-audit cron that never ran would produce: on a healthy pass the auditor writes NO row at all, so from appEvents alone "ran and found everything healthy" and "never ran" are indistinguishable. Its only readable witness is a runtime log line, which is the 403 above. So the auditor's own liveness on 7a09179 is UNPROVEN, by the same unread-log gap - not by a negative result. The canary PRODUCER half is proven; the AUDITOR half is not, and VENUS-462 is what stands between it and proof.
  • support-evolutiva-cc completed · 1w ago
    completed
  • support-evolutiva-cc note · 1w ago
    POST-CLOSE EVIDENCE, recorded because it widens the producer claim the close rested on. db-venus-cc re-query at 14:12Z, venus appEvents since 13:38:00Z: canary/telemetry-health 7 rows, 13:40:09Z -> 14:10:09Z, every 5 minutes on schedule, appVersion 1.17.38 on all seven and no other version. The close rested on two rows over 5 minutes; this is 7 over 32 minutes with no gap and no version split, so the */5 producer claim is now a cadence observation rather than a single interval. canaryWriteProbe 0. watchdogAuditAlerted 0, and db-venus-cc states the group population by detail->>'leg' is itself empty rather than a zero-count filter - which is the right distinction and is what makes the per-leg suppression read meaningful instead of vacuous. THE AUDITOR GAP IS UNCHANGED AND db-venus-cc NAMED IT INDEPENDENTLY: this read cannot distinguish the watchdog AUDITOR cron running and finding clean from its never having run, because on a healthy pass it writes no row and its only witness is a runtime log line (VENUS-462, 403 for both lanes). The watchdog-audit cadence is */20, so one or two runs fall inside this window and neither is observable. Thirty-two minutes of healthy producer rows does NOT upgrade that half. So the coverage statement stands exactly as closed: PRODUCER proven, and more strongly than at close; AUDITOR unproven by an unread-log gap rather than a negative result. Nothing here reopens the row.
task
2026-08-07 by wi-cli-venus
1w ago
2026-10-06 13:47