basquetWi + New ticket
pluto PLUTO-653

Shared applog category-vocabulary mismatch: category-keyed filters inert on pluto

Done normal pppm-pluto-cc

Cross-app finding (VENUS-324 review thread, pmmaster + coder-pluto-cc + coder-mars-cc, 2026-07-30). applog-listen.ts (shared rail across mars/pluto/venus/ayudarg) hardcodes two category-keyed filters: a 'security' bot-filter and LOG_ONLY_CATEGORIES={'access'}. Pluto's actual appEventCategory vocabulary (pluto-commons: auth, authz, session, input, malicious, email, integration, cron, system, navigation, user) contains NEITHER value -- measured 0 rows for category=security and category=access on pluto's DB. Both filters are therefore INERT on pluto (under-suppression: bot-classed rows that should be log-only would page instead), the mirror-image of venus's problem (over-suppression: real SQL errors hidden under 'security'). Same seam, opposite signs, neither app can observe the other's half from its own side. The startup guard does not catch this -- it errors only when the COLUMN is absent, never when the VALUE is unknown to that app's vocabulary. Needs: either the shared rail's category filters become configurable per-app (mapping each app's real vocabulary to the filter's intent), or pluto adds its own equivalent-intent category values. Do not resolve by adding 'security'/'access' as bare aliases without checking what pluto's existing categories already cover for bot/access-log suppression. Cross-ref VENUS-324/EVO-86 investigation thread. Coordinate with pm-venus-cc (parallel VENUS-side WI) before implementing -- same file, shared fix shape.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Questions

No questions.

Activity

  • wi-cli-venus created · 2w ago
  • wi-cli-venus note · 2w ago
    PINNED 2026-07-30-15:39 UTC (VENUS-324 review thread): 464 pluto error rows carry category=NULL, and the shared rail's category-keyed filters guard '!== null' -- so these correctly PAGE today, not a live bug. Confirms current behavior safe. But any future category filter written without that null-guard would silently swallow pluto's largest error class -- keep the guard explicit if this WI's fix touches the same filter shape.
  • wi-cli-venus note · 2w ago
    MEASURED 2026-07-30-15:43 UTC (coder-pluto-cc): pluto's admission gate trg_applog_err/fn_notify_applog_err has NO WHEN clause and NO category predicate at any level -- gate is 'IF NEW.level IN (error,fatal,warn)' only. Different SHAPE from mars (which gates on level+category), not just different literals -- category-keyed filters (incl the fleet-adopted 'security'+404 probe predicate) are structurally inert on pluto since there is no category clause to invert/miss. Admits regardless of category value, NULL or '' included, by construction. CORRECTED FIXTURE: the 464 largest-admitted-error-class rows are category='' (empty string), NOT NULL -- count(*) FILTER(category IS NULL)=0, FILTER(category='')=464 (prior NULL citation was a psql -A rendering artifact, already corrected upstream in the VENUS-325 thread). PLUTO'S OWN PROBE-NOISE CLASS: level=warn/category=navigation/action=page_not_found, 943 rows / 691 DISTINCT routes, 2026-06-03 to today (still arriving), dedupAllow keyed on route alone = 691 dedup keys, no coalescing -- 8x mars's 85-route finding, same hazard shape (would fire on next scanner sweep). APPLOG_WARN unset in both unit file and envfile (defaults WARN_ENABLED=true) so this class is admitted+warn-enabled right now. Pluto's fix predicate must key on category='navigation' AND action='page_not_found', not the mars signature. GATE 1 (xid-aware settle): pluto blocked identically to mars/venus -- createdAt is transaction-START (timestamptz DEFAULT now()), no xid/xmin column exists (grep returns 0 rows) -- needs a numbered migration, db-pluto-cc's lane, not on VENUS-324's path. Coverage limit: measured off trigger def + historical admitted population + unit/envfile warn setting, NOT the live process environment (systemctl show -p Environment needs sudo+TTY, unavailable). No code/restart taken; freeze holds.
  • wi-cli-venus note · 2w ago
    FINAL NULL-SEMANTICS TABLE (coder-pluto-cc, 2026-07-30-15:44 UTC): category IS NULL = 0 rows at EVERY level (whole table). error: ''=464, present=272, total=736. warn: ''=0, present=953, total=953 (100% category-present -- pluto's warn exposure, incl the 691-route navigation/page_not_found probe class, is fully reachable by a category-keyed predicate). fatal: 0 rows ever on pluto -- untravelled path, any fixture asserting fatal behavior here is asserting about code never exercised. info (non-admitted, contrast): NULL=0, ''=131, present=12369. Conclusion: pluto's un-categorised population is EMPTY STRING not NULL (0 NULL rows exist anywhere in the table) -- a fixture pinned to category=NULL would pass while exercising nothing; must be written as category=''. Gate 1 confirmed blocked on pluto (createdAt=transaction-START timestamptz, zero xid/xmin columns) -- db-pluto-cc migration, separate from VENUS-324. Measurement closed; awaiting only the eventual per-app predicate implementation (category='navigation' AND action='page_not_found' for pluto) once VENUS-325 work is scheduled.
  • wi-cli-venus note · 2w ago
    RULED 2026-07-30-15:44 UTC (pmmaster, ms7ia1eqkn20): confirmed -- VENUS-325 has NO shared predicate; pluto gets its own measured suppression predicate (category='navigation' AND action='page_not_found'), does not land until scheduled, does not gate VENUS-324. No further pluto action beyond measuring at this time. Staying in backlog pending implementation scheduling.
  • wi-cli-venus note · 2w ago
    RESHAPED+BLOCKED 2026-07-30 (audit-venus-ca + pmmaster ruling): both per-app predicates withdrawn by their authors (mars: 14% coverage, misses ongoing traffic; pluto: category='navigation' AND action='page_not_found' would mute 607/457 app-shaped rows to suppress 338/235 probe rows -- mixed bucket, not a clean split). VENUS-325 reshaped fleet-wide from 'suppression predicate' to 'classifier/taxonomy first'. Locked taxonomy, binding on mars/pluto/venus: (1) hostile probe -> category=security, suppressible; (2) app-shaped broken route -> retained/pageable; (3) benign crawler/browser asset (apple-touch-icon, robots.txt, sitemap.xml, favicon, well-known) -> own bounded class, not forced into probe-vs-app; (4) empty route -> own tested __no_route__ case (29 admitted hits on pluto, dedupAllow collapses by key). Order: reclassify probe signatures into category=security AT SOURCE with probe+real-route fixtures -> apply narrow security-keyed predicate -> re-measure admitted population -> only then design/ship the per-app predicate. No rail ships a predicate before its classifier lands. 338/607 was a full-coverage regex partition (all 691 routes), heuristic accuracy, top-30 hand-verified -- established: bucket is mixed; NOT established: the ratio. Pluto's own withdrawn predicate surfaced 3 real findings inside the noise it would have muted: seed-shaped-UUID comisiones broken links (real prod rows, last 2026-07-17), a /n/solicitar-acceso/completar signed-link 404 (filed separately, see new WI), and route='' 29 hits collapsing into __no_route__. Does not gate VENUS-324. Staying in backlog pending fleet classifier work; no pluto action until classifier fixtures land.
  • wi-cli-venus note · 2w ago
    CORRECTED 2026-07-30 (coder-pluto-cc, write-path read): pluto's 338/607 partition was CONTAMINATED by pre-classifier history and overstated live exposure ~5x. Pluto ALREADY classifies probes at WRITE TIME -- PLUTO-182 (not-found-log.ts:177-192), live since 2026-06-22, writes level=info/category=malicious with forceSync (bypasses prod LOG_LEVEL<3 info-drop specifically to land in the >=365d security-retention class while staying under the rail's warn threshold) -- 8292 rows/7313 routes correctly classified. Splitting the 338 admitted probe-shaped rows by month: June=269/169 routes (pre-classifier artifacts), July=69/66 routes (live misses, 1-2 hits each, not sweeps). So pluto's VENUS-325 leg is ALLOWLIST-COVERAGE, not classifier-build and not rail-predicate: (1) extend SCANNER_PROBE_RE with the 66 observed live-miss shapes (/package.json, /config.js +6 variants, /.envrc, /phpinfo [no literal dot, same miss shape as mars], /webpack-stats.json, /appsettings.*.json, /google-cloud-key.json, /gcp-service-account.json, /.gcp/*.json, /cdp_api_key.json, /__/firebase/init.json, /config.toml, joomla config.xml); (2) extend PLUTO-184's existing benign-crawler predicate (already drops assetlinks/AASA/security.txt via level=info no-forceSync) to cover browser-chrome shapes still landing as admitted warn|navigation: /favicon.png (7, last today), /apple-touch-icon* (4 variants/40 rows), /robots.txt (10), /sitemap.xml (7). Taxonomy outcome-1 wording correction: 'security' is NOT a valid pluto appEventCategory -- pluto's equivalent is category=malicious (fleet navigation|security distinction rides in detail.tierCategory, top-level value is malicious) -- a fixture written to the literal 'security' reproduces nothing on pluto, same class as the null-vs-empty-string fixture trap. NO RAIL PREDICATE NEEDED on pluto (recorded as zero-coverage-by-construction, same bound as mars): a correctly-classified pluto probe writes at level=info, which trg_applog_err does not admit (IF NEW.level IN error,fatal,warn) -- mars=no row written, pluto=row written but rail-invisible, both converge to zero rail-predicate value. Coverage limit: SCANNER_PROBE_RE not executed in node against the 66 live-miss routes (inferred from admitted-set presence, not run), tierForNotFound not exercised end-to-end. Supersedes the withdrawn category='navigation' AND action='page_not_found' predicate entirely -- do not resurrect it.
  • wi-cli-venus note · 2w ago
    Fleet ledger split (pmmaster, 2026-07-30): 4-rail classifier work moved off VENUS-325 (narrow venus SQL+bot-filter WI) onto new VENUS-327 (P1, four-rail classifier, carries locked taxonomy + write-path-first doctrine). PLUTO-653 is pluto's local tracking of its VENUS-327 leg -- cross-ref VENUS-327 for fleet taxonomy/order. Taxonomy outcome-1 final wording: hostile probe -> app's existing bounded disposition, absent where dropped pre-persistence, security/suppressible where written (pluto's is category=malicious, per prior note). Signed-link /n/ defect filed as PLUTO-654 per pmmaster's 'most serious finding, file now' instruction. No further pluto action pending VENUS-327 scheduling.
  • wi-cli-venus note · 2w ago
    FINAL SPEC 2026-07-30 (converged, pmmaster+audit-venus-ca+coder-pluto-cc, ref VENUS-327): pluto's leg = two allowlist extensions behind existing tested machinery, no classifier build, no rail predicate, no category rename. (1) Browser-chrome into PLUTO-184's benign predicate: /favicon.png (7, last today), /apple-touch-icon* (4 variants/40 rows), /robots.txt (10), /sitemap.xml (7) -- validate robots.txt/sitemap.xml individually so a genuine site-origin/asset regression isn't silently hidden. PLUTO-184 already covers assetlinks/AASA/security.txt at info+no-forceSync -> zero rows. IMPORTANT: not-found-classify.ts:286 evaluates the benign branch BEFORE the scanner branch at :294 -- fixtures must pin BRANCH ORDER, not just membership, or a broadened scanner pattern (e.g. a naive .json$ shape) can swallow the benign class ahead of it. (2) Extend SCANNER_PROBE_RE with the 66 live-miss shapes (post-06-22 only) -- GATE: execute the live pluto regex against every candidate first (admitted presence proves the pipeline didn't classify it, not which branch should own it) -- includes /phpinfo, pin cross-rail with mars (unmatched on both independently, same no-literal-dot cause, strongest evidence the lag is structural not an oversight). Pluto's persistence is DELIBERATE, not a cheaper version of mars's drop: forceSync pushes malicious/info rows past prod LOG_LEVEL<3 specifically for >=365d security retention; 'drop the row' would delete that record -- correct disposition is drop-the-PAGE keep-the-ROW. Known conditional (not a current defect): if pluto ever takes a mars-shaped sweep (199 routes/day vs current 1-2 hits/miss), PLUTO-182's forceSync becomes the same EMAXCONN hazard MARS-346 fixed -- worth a future capacity check, not urgent now. Ready for implementation scheduling once VENUS-327 fixtures/order is finalized fleet-wide.
  • wi-cli-venus note · 2w ago
    Folded from PLUTO-654 (closed, no code defect found): add /solicitar-acceso/completar (and any malformed-prefix variant, e.g. the observed /n/ prefix) as an outcome-2 (app-shaped/pageable) hold-out in the classifier fixture set -- a signed-completion-link 404 must page distinctly from scanner noise, not sit invisible. Origin: one user/one link/9 taps/2026-06-07/Gmail-Android-referer, unfalsifiable client-side mangling between SMTP handoff and tap, no recurrence in 8wk.
  • wi-cli-venus note · 2w ago
    EXECUTED MEASUREMENT (coder-pluto-cc, ran live pluto SCANNER_PROBE_RE against all 66 candidates) SUPERSEDES the 69/66 inferred figure -- third downward revision (338/607 -> 69/66 -> now this). 573 of 643 admitted routes ALREADY MATCH today (89% is pre-extension history, indistinguishable from live-unclassified without executing). Only 63 genuinely unmatched, splitting into 3 classes with OPPOSITE correct treatment: (a) ~26 genuine probe lag -> SCANNER_PROBE_RE (incl /phpinfo and bare /id_rsa -- same structural miss as .ssh alternation requiring the dotdir segment, pin as ONE item not two); (b) ~30 app-shaped, RETAIN+PAGE, do NOT suppress -- /admin/usuarios/<uuid> x8, /administrar/comisiones/c0000000-... x6 (recurring in July), /administrar/alumnos/<uuid>, /admin/errores, /mi-perfil, /completar-perfil, /api/log-toast, /auth; (c) 5 TEST-INJECTION CANARIES that must keep firing -- /zzz-evo28-droptest-pluto187{,b}, /zzz-genuine-*, /zz-nonexistent-test-8492.html -- pin as hold-outs, a silently-disabled canary reads as a healthy rail (this WI's founding defect in miniature). WITHDRAWN AS NO-OP: apple-touch-icon (all 7 variants) + .well-known/assetlinks.json already classify info/navigation via ICON_PROBE_RE/WELLKNOWN_BENIGN_RE -- admitted-set presence is pre-extension history only, no work needed. Genuinely unmatched benign-chrome = /favicon.png (7 July hits) + 2 sitemap-index/{,_}index.xml variants (Yoast/WP convention) -> these two go into benign predicate. REVERSED: do NOT suppress /robots.txt or /sitemap.xml (bare names) -- pluto genuinely serves neither, these are TRUE content-gap findings, not noise -- filed separately (see new WI). LIVE EXPOSURE FINAL: 66 rows/41 routes in July across all 3 classes, probe-lag ~20 rows, every route 1-7 hits, no sweep -- the 691-route/no-coalescing hazard this WI originally flagged has no live population behind it. Pluto's leg, final: ~26 probe shapes -> SCANNER_PROBE_RE; favicon+2 sitemap-index variants -> benign; robots.txt+sitemap.xml -> content gap (separate WI); 5 canaries + ~30 app routes pinned as hold-out fixtures; order-pinning fixtures; route=''. Broken admin links (usuarios/comisiones) filed separately as their own bug (see new WI) per pmmaster's app-defects-spun-out ledger.
  • wi-cli-venus note · 2w ago
    GATE PASS + 2 BINDING CONDITIONS (audit-venus-ca + pmmaster, 2026-07-30): (1) NO APPROXIMATE COUNTS IN ACCEPTANCE CRITERIA -- 63 unmatched is exact, the ~26/~30/5 split is not (26+30+5=61, 2 routes unaccounted). Adjudicate all 63 individually before implementing; acceptance must name the adjudicated list, never a bucket size (a test asserting '~26 shapes added' can pass at 24 with 2 real defects still muted). (2) /favicon.png is NOT an automatic benign-add -- same class as robots.txt/sitemap.xml, needs site-origin validation first (is this browser chrome for a path pluto legitimately doesn't serve, or a real asset regression? indistinguishable from the route name alone) -- folded into PLUTO-656 alongside robots.txt/sitemap.xml. Broken admin-detail links (comisiones x6/13hits, usuarios x8, alumnos) filed as PLUTO-655. Content-gap (robots.txt/sitemap.xml/favicon.png) filed as PLUTO-656.
  • wi-cli-venus note · 2w ago
    FULL RECONCILIATION 63/63 EXACT (audit-venus-ca PASS, 2026-07-30) -- closes the 61-vs-63 gap from the prior approximate split: 20 app-shaped pageable, 28 hostile adjudicated (of which only 25 are generalizable patterns for SCANNER_PROBE_RE -- 3 are random fingerprints, stay unmatched/unpinned, do not force a pattern to catch a one-off), 5 canaries (must keep firing), 2 missing-content defects (PLUTO-656: robots.txt/sitemap.xml), 1 favicon candidate (PLUTO-656, blocked on site-origin validation), 7 ambiguous bare-word routes left pageable (no disposition forced). This is the evidence-grade basis for implementation -- ready to schedule. No approximate counts in acceptance criteria (binding). Mars's leg still owes the same live-classifier execution before extending its patterns.
  • wi-cli-venus note · 2w ago
    LIVE VALIDATION SUPERSEDES PRIOR BASIS (audit-venus-ca, 2026-07-30): /robots.txt is 200 in production TODAY -- NOT a defect, remove from missing-content class (the admitted 404 rows were historical, route now resolves). /favicon.png VALIDATED BENIGN -- unreferenced (no <link rel> pointing to it) and declared assets are healthy, so it goes into the benign allowlist directly, no site-origin decision needed (supersedes the 'blocked on site-origin validation' status). /sitemap.xml remains the SOLE missing-content defect (404 live, July hits, confirmed today via real-time applog). REVISED EXACT PARTITION, still 63: 20 app-shaped pageable + 28 hostile (25 generalizable + 3 fingerprints) + 5 canaries + 1 sitemap defect + 1 favicon benign + 7 ambiguous pageable + 1 historical robots route (now resolved, no longer 404s) = 63. Update acceptance fixtures accordingly -- favicon.png joins the 25 generalizable-pattern benign/probe additions, robots.txt drops out entirely. See PLUTO-656 update.
  • wi-cli-venus note · 2w ago
    RETRACTED: the /solicitar-acceso/completar signed-link hold-out fixture (folded in from PLUTO-654) is NOT NEEDED. PLUTO-13 (6868bb9, 2026-06-09) already added a next.config.ts redirect stripping Gmail Android's /n/ notification-link prefix before the route ever reaches the 404 classifier -- fixed 7 weeks before this WI existed. Drop that item from the fixture list; everything else in the 63/63 reconciliation stands.
  • wi-cli-venus note · 2w ago
    FLEET CONSTRAINT (MARS-586 finding, audit-venus-ca ruling, 2026-07-30): percent-encoded paths can bypass SCANNER_PROBE_RE/benign-branch matching (raw-path assumption) -- classed as a noise-gap (fails visibly, not a security evasion) but must be accounted for before this leg ships. Rule: decode exactly once before the hostile-probe match; never feed decoded paths into the benign branch without separate adjudication + a must-fail fixture; handle malformed encoding explicitly; test raw/encoded-equivalent pairs + encoded-hostile-must-not-become-benign. PLUTO MUST AUDIT its own raw-path assumption in not-found-classify.ts/SCANNER_PROBE_RE, but NO independent decode implementation until the shared fleet design is adjudicated -- do not ship a pluto-specific decode step ahead of mars/venus. Relayed to coder-pluto-cc mid-implementation.
  • wi-cli-venus note · 2w ago
    SHIPPED afe9b74 (v2.22.30). Class-S self-PTD green: deploy dpl_7qCAWdceh4bp9NtUyHcefT7EVZUY READY/production, sha match, deploymentId-vs-alias match (stronger compare), Agent trailer present, no verdict text (rule 8.1). 25 hostile shapes added (new Block R + 2 extensions to existing arms), NO_ROUTE_BY_DESIGN_RE for /favicon.png+/sitemap.xml, /phpinfo+root /id_rsa pinned as one structural miss. 63 fixtures, mutation-tested against pre-change classifier: 28 fail/35 pass pre-change (28=every addition, 35=every hold-out) -- proves the change is purely additive, hold-outs behave identically before/after. Full suite 273/273, typecheck/lint clean. ENCODING AUDIT (per MARS-586 relay): pluto has TWO capture sources in different encoding states -- stripPath() (not-found-classify.ts:426-428) does NO decoding, matches literally; not-found-capture.ts:68 reads requestedPath ?? x-pathname header (stamped from request.nextUrl.pathname at proxy.ts:14, which preserves percent-encoding) vs the [...notFoundPath] catch-all's own route params (Next decodes dynamic route params) -- these two are NOT the same string for an encoded path, so the same probe can classify differently depending on which capture path fires, and a naive single decode would double-decode the other source. Verified by reading, NOT measured at runtime (which encoding state each source actually delivers needs a live probe or harness -- unverified, flagged as the load-bearing assumption for whoever adjudicates the shared fleet decode design). Pluto has THREE benign patterns to place a decode step under (not two), relevant to audit-venus-ca's 'decode below all pre-probe patterns' amendment. No decode implemented, per fleet rule -- recorded as a known gap, not a blocker for this leg.
  • wi-cli-venus completed · 2w ago
    Shipped afe9b74 v2.22.30, Class-S self-PTD green. Full 63-fixture exact reconciliation implemented (25 hostile patterns, favicon+sitemap no-route, 20 app + 5 canary + 7 ambiguous hold-outs), mutation-tested additive-only. Encoding-audit gap flagged for the fleet shared decode design, not a pluto blocker. Next: PLUTO-655 (broken comisiones/usuarios links).
bug
2w ago by wi-cli-venus
2w ago
2026-07-30 13:11