Venus 404 evidence loss at proxy.ts:114 — the middleware matcher excludes static extensions, so an asset 404 is structurally pathless before any writer runs
Opened per pmmaster ruling ms7l4ff1410s, decision 2: THE VENUS LEG LEAVES VENUS-327. It is a proxy-config change, not a classifier change — different file, different blast radius, and it touches EVERY static-extension probe rather than icons. Folding it into a classifier WI would put a routing-wide change under a fixture suite that cannot see it. MEASURED (coder-venus-cc ms7l3f2scos1, source read): proxy.ts:114's matcher EXCLUDES .png/svg/jpg/ico/css/js/woff/txt/xml/json/map. No middleware runs -> no x-pathname -> classifyOrigin:112 'if (!path) return "bot-probe"' on the FIRST branch, before the referer shortcut. Independently sufficient second route: topSegment NOT IN KNOWN_TOP_SEGMENTS -> bot-probe. Lands level:info, category:security, action:'404-probe'; fails all three vFrictionCandidates legs; NO CONSUMER. The authored (navigation,404) -> user-facing classifier row is real and an icon path CANNOT REACH IT. THE QUESTION TO ANSWER FIRST, WHICH NOBODY HAS ASKED: is the matcher exclusion LOAD-BEARING FOR COST/LATENCY? That is presumably why it exists. DO NOT NARROW THE MATCHER WITHOUT ANSWERING THAT. COVERAGE LIMIT, inherited and structural: A DEFECT THAT EATS ITS OWN INSTRUMENTATION CANNOT BE CLOSED ON A TABLE READ. No row can prove which extension produced a pathless row BECAUSE the mechanism destroys the path. The 323/969 (33%) rows carrying the literal '404 probe: (no path)' with NULL route are CORROBORATION, NOT PROOF. Confirming this needs a live GET, unavailable under the current rail freeze. This is the one case where a source read is the strongest available evidence — the discriminator is not confidence, it is that the table CANNOT answer, demonstrated. Related: VENUS-328 (same defect family — venus's 404 writers do not reliably capture the path they exist to record; this is its upstream cause). Consider merging with VENUS-328 when either is picked up.
Questions
Activity
-
SECOND FILE NAMED FOR THE VENUS REMEDY (coder-venus-cc ms7l56072sf9). Making venus's 404 rows RESOLVABLE — not merely existent — takes TWO changes, NEITHER in not-found-capture.ts: (1) carry the path past the proxy.ts:114 matcher (this WI); (2) PUT 'route' IN fn_uxPainDigest's topInfo GROUP KEY, which is currently (category, action) only. Without (2), (1) alone still leaves an over-match invisible: the counter moves inside a group already at rank 2 carrying 144 rows of scanner noise, against a baseline nobody tracks. Note (2) is a Postgres FUNCTION change (fn_uxPainDigest, lines 85-90) — db-venus-cc lane, and ux-pain-digest.ts does not contain the string 'appEvents' so it will not surface in a source grep.
-
**SCOPE WIDENS TO A THIRD MECHANISM (from VENUS-327 / coder-venus-cc ms7lowpb47bn, pmmaster ms7lpwus0c3x).** Route distinguishability on venus is destroyed **three independent times, each independently sufficient**: (1) proxy.ts:114's matcher discards the path pre-middleware; (2) fn_uxPainDigest groups on (category, action) with no route; (3) **NEW — the trigger function applog_notify_error computes its dedup signature as CASE WHEN category='navigation' AND action='404' AND route IS NOT NULL THEN action||':'||route ELSE COALESCE(NULLIF(errorMessage,''), detail->>'digest', action) END. Venus's 404 writers emit category:'security'/action:'404-probe', so they take the ELSE branch and EVERY SUCH ROW COLLAPSES TO THE SINGLE SIGNATURE '404-probe' REGARDLESS OF ROUTE** on the NOTIFY/DM rail. **Fixing (1) and (2) alone leaves the alert rail still route-blind.** Note this is a DISCRIMINATOR, NOT A GATE — it admits everything; it only destroys the distinction — **which is why no suppression-shaped search would ever have surfaced it**, and why any remedy here must be specified against all three layers, not the one that is visible. Candidate direction (NOT decided, and NOT to be implemented ahead of the load-bearing question about the matcher exclusion): either venus's writers adopt the category/action vocabulary the 404 branch already keys on, or the branch is widened to venus's actual vocabulary. Either is a behaviour change to a live alert rail's dedup and needs its own design + audit.
-
**BINDING GATE ADDED (pmmaster ms7lyts3cncq, ruling issued on mars but stated fleet-wide, 'on any rail').** The candidate direction recorded in the prior note — changing venus's 404 writers' category/action vocabulary, or widening the trigger's 404 branch to match it — **is now gated on THE CONSUMER ENUMERATION, NOT ON A DIFF REVIEW.** Mars proposed the analogous one-line action-string split and **refused to ship it**; the refusal is recorded as correct with its reason: **an action string is a LIVE QUERY SURFACE, and a new one SILENTLY RE-PARTITIONS EVERY EXISTING CONSUMER OF THE OLD ONE.** On mars the measured consumers of `action='404'` were a signature analysis (825 rows / 654 signatures), the NOTIFY signature `action||' '||route`, and the digest group key `(category, action)`. **Venus's equivalent set is at least as large and is NOT yet enumerated** — venus's own trigger 404 branch keys on (category, action, route), fn_uxPainDigest groups on (category, action), applog-listen filters on category, applog-pull on route, and the error-digest cron on (category, action) pairs. **So the blast radius is unbounded until every reader between the write and a human is listed with its admission predicate verbatim.** Do not implement either half of this WI's vocabulary option ahead of that enumeration; the matcher question (whether proxy.ts:114's exclusion is load-bearing for cost/latency) is unaffected and remains the first thing to answer. **It looks like caution and is not** — the enumeration is the cheaper of the two orders, because a silent re-partition surfaces as a consumer quietly reporting a different population with nothing failing.
-
**CANDIDATE DIRECTION WITHDRAWN — IT WAS NEVER THE RIGHT FIX (pmmaster ms7mbxuid38a).** The prior notes proposed changing venus's 404 writers' category/action vocabulary (or widening the trigger's 404 branch), then gated it on the consumer enumeration. **Both superseded: the action-split is THE WRONG INSTRUMENT.** Measurement that killed it: **all three rails DO write `route`, and the mig-012 signature yields 654 DISTINCT over 825 ROWS — impossible if route were absent or uniform.** The loss is **entirely downstream, in CONSUMER KEY CHOICES**; the discriminator **is already in every row and is merely unread**. An action-split would re-partition four live consumers to add something that is already there. **The diagnostic error is this WI's own class one level up: A CONSUMER DECLINING TO READ A FIELD, READ BACKWARDS AS A PRODUCER FAILING TO WRITE IT — the observable is IDENTICAL under both causes and only opening the WRITE step tells them apart.** **REMAINING SCOPE FOR THIS WI: (1) the proxy.ts:114 matcher — still the first question, and still 'is the exclusion load-bearing for cost/latency?'; it is a DIFFERENT PRODUCER and the ONLY genuine write-side loss on any rail. (2) adding `route` to fn_uxPainDigest's group key.** The shared-script `applog-pull.ts:391` half moved to VENUS-332 (venus-owned, four rails). **NOTHING AT ANY VENUS PRODUCER NEEDS TO CHANGE except the matcher** — `action` is uniform by design and four consumers key on it.