El drain de email de terra reporta Result=success, pero nadie verifico que haya ENVIADO algo: una cola vacia y un envio real son el mismo exit 0
Filed by pmmaster-evolutiva-cc 2026-09-11 under Elazar delegated GO. Direct follow-on from your TERRA-223 coverage statement, and it is the harder half of the same question. THE SITUATION. Terra email now drains through the venus systemd rail, evolutiva-emaildrain@terra. bin-venus-cc verified the 12:55 run went through the reloaded unit with Result=success, and enamel was cut over the same hour with its first timer run at 13:00:01 UTC also success. Result=success means the unit exited 0. It does NOT mean mail was sent. WHY THAT GAP IS NOT THEORETICAL HERE. VENUS-398 is open on exactly this defect one app over: the drain writes NO appEvents row on the empty path, so a timer that never fires and a timer that fires and finds nothing are indistinguishable. Terra has just been moved onto the same rail. If terra queue was empty during those runs, every observation we have of the terra cutover is compatible with the drain being completely broken. WHAT TO DETERMINE, and answer each separately rather than as one verdict: (1) how many rows sat in terra outbox during the observed window; (2) how many left it, by what evidence - a status transition, a sentAt, a delivery record, name which; (3) whether any row has been sitting unsent since before the cutover, which would be silent mail loss rather than a quiet queue. IF THE QUEUE WAS EMPTY THE WHOLE WINDOW, that is the answer and it is a legitimate one - say so plainly and say that the cutover is therefore UNVERIFIED, not working. Do not report an empty queue as a successful drain. The honest next step in that case is a single deliberately enqueued row, which is coder-terra-cc lane to enqueue, not yours to manufacture. KNOWN LIMIT ON YOUR ACCESS, carried from TERRA-223 so you do not rediscover it: audit_terra_cc_ro has no grant on appEvents and no views at all. appEventRelays is granted. If the answer lives in appEvents, stop and say so rather than inferring from an adjacent table - I have asked db-enamel-cc for that grant today. Verdict form is a coverage statement naming what you could not read. Absence of exercise is not verification.
Activity
-
Cannot answer (1)/(2)/(3) - no plane I can reach carries this evidence, and one code-level fact means even the appEvents grant pmmaster requested from db-enamel-cc today will NOT close this row by itself. MECHANISM READ (drain-route.ts + outbox-core.ts, source only): the venus timer (evolutiva-emaildrain@terra.timer, 5min cadence, confirmed live via systemctl --user - last fire 13:05:00Z, exit 0) does a bare authenticated GET. drainOnce() claims up to 10 rows and sends sequentially. appEvents gets a row ONLY on: (a) auth failure with secret unset, (b) a route-level throw before any row settled, (c) a row permanently exhausted after retries, (d) reclaimed>0 (a prior run died mid-send). This is DELIBERATE, not the VENUS-398 accident - drain-route.ts:107-116 explains it in-comment: appEvents is shared with enamel and a per-tick heartbeat would be terra polluting a co-tenant's table. CONSEQUENCE: a run that claims 0 rows and a run that claims and successfully sends 10 rows produce IDENTICAL output on every plane outside emailOutbox itself - 200, exit 0, zero appEvents rows, zero extra log lines. So (1) claimed-count and (2) sent-evidence live ONLY in emailOutbox (claimedAt/sendStatus/sentAt), never in appEvents, regardless of grant. WHAT I CHECKED: journalctl --user for evolutiva-emaildrain@terra.service - only shows the curl invocation and exit code (200/exit 0 at 12:50, 12:55, 13:05Z), no response body (curl runs --silent). Vercel runtime logs for the serving deployment, 09:55-12:55Z window - two GET /api/cron/drain-email-outbox 200 hits, no additional log lines (matches the code: a clean run at any volume logs nothing beyond the request line). WHAT I CANNOT READ: emailOutbox (has_table_privilege=false, confirmed) and appEvents (has_table_privilege=false, confirmed) - both deliberately excluded from audit_terra_cc_ro. Neither the response body nor any independent send-provider log is reachable from this lane (transport is direct SMTP via nodemailer, no third-party dashboard to cross-check). VERDICT: UNVERIFIED, not working, and specifically not 'empty queue is the answer' - I have no evidence the queue was empty either. The observable planes (systemd exit code, Vercel status, appEvents) cannot distinguish an idle drain from a working one AT ANY QUEUE DEPTH, by design. Closing this needs an emailOutbox grant (SELECT on claimedAt/sendStatus/sentAt/attempts is enough, no PII columns needed for a count-and-timestamp read) - the appEvents grant already in flight does not cover it. Not mine to enqueue a test row per the row's own instruction.
-
Needs SELECT on emailOutbox (claimedAt/sendStatus/sentAt/attempts) for audit_terra_cc_ro - the in-flight appEvents grant does not cover this, per code a clean drain at any volume logs nothing to appEvents. Ask db-enamel-cc.
-
appEvents grant landed (db-enamel-cc). Checked: zero rows ever for appKey='terra' AND categoryValue='cron' - no drain-email-outbox-failed, no -exhausted, no -reclaimed, no secretUnset, in the entire table history, not just the window. Rules out auth failures, route throws, permanently-failed rows, and stale-claim reclaims at any point since this rail went live. Does NOT rule out a broken claimBatch query that throws before reaching the try block's own catch (drainOnce swallows that silently per line 339-341, returning zeros with no re-throw and no log) - a specific gap worth naming since it means even a route that ALWAYS reports claimed:0 sent:0 without ever failing loudly is indistinguishable from a healthy empty queue from this table alone. Still blocked on emailOutbox for claimed/sent counts and timestamps - this narrows but does not close the row.
-
emailOutbox column-grant landed (db-enamel-cc, 16 cols, PII cols excluded). Queried directly, whole table: 2 rows ever. terra: 1 row (d87259ae, accessIssue), claimedAt=10:55:00.858Z, sentAt=10:55:05.048Z, attempts=1, sendStatus=sent - one real end-to-end success, BEFORE the observed 12:49-13:05Z window this row was filed about. enamel: 1 row, pending since 10:30:15Z (not terra's concern). Zero failed/exhausted/reclaimed rows ever, matches the empty appEvents cron history already found. ANSWERING THE ROW'S THREE QUESTIONS: (1) rows in outbox during the 12:49-13:05Z window: zero - queue was empty the whole window, confirmed from emailOutbox directly, not inferred. (2) rows that left during that window: none, none existed to leave. (3) any row sitting unsent since before cutover: no, whole-table history is 2 rows total, neither pre-dates today. VERDICT: the observed window's cutover is UNVERIFIED-BY-VOLUME (queue empty, confirmed, not merely inferred from silence) - correct per the row's own framing, not a broken drain. Separately, the pipe has one genuine successful precedent at 10:55:05Z (claim-to-send in 4.2s) that DOES demonstrate send capability end-to-end, just not inside the window this row asked about. No sign of the VENUS-398 defect actually firing (nothing has ever needed to be logged), but the code-level exposure ([[a-clean-cron-drain-is-silent-at-any-volume]]) stands regardless - it would look identical to this if the drain silently broke tomorrow.
-
cleared: Needs SELECT on emailOutbox (claimedAt/sendStatus/sentAt/attempts) for audit_terra_cc_ro - the in-flight appEvents grant does not cover this, per code a clean drain at any volume logs nothing to appEvents. Ask db-enamel-cc.
-
Queue was empty the whole observed window, confirmed directly from emailOutbox (not inferred). One genuine successful send exists pre-window (10:55:05Z). Verdict: UNVERIFIED-BY-VOLUME for the cutover claim, not a broken drain.