Fleet appEvents schema standardization (mirror MARS-411) — DESIGN-HOLD
Mirror of Mars leg MARS-411 (fleet appEvents standardization, filed pm-mars 2026-07-07). Contract goal: single log(entry) entry-point (level-as-data, not level-named helpers), promote HOT fields to real scalar columns, reserve jsonb ONLY for irregular data. DESIGN-FIRST — nobody builds until the fleet column contract is agreed AND Elazar sees scope. Pluto-specific reconcile flags: 1. Codex source prompt (f3m8wm) is SQLite-shaped (INTEGER pk, TEXT ts, app_log). Pluto adapts the SHAPE onto live Supabase appEvents (uuid pk, timestamptz, camelCase) — NO parallel SQLite table. Our vAppEvents25/50/100 (PLUTO-532) already promote the hot scalar set (createdAt/level/category/action/status/route/actorUserId/effectiveUserId/message/errorName/errorMessage/appVersion) + exclude jsonb detail — that curated set is a de-facto hot-column candidate list for this contract. 2. 'no wrappers' targets the logError/logWarn/logInfo helpers (Pluto has logWarn from PLUTO-461, logError, logCaughtError) — directive = collapse into one log({level,...}). Confirm intent before any coder rips them out; interacts with the PLUTO-529 no-silent-failure retrofit (shared mutation-wrapper also routes through logError) — sequence so the two don't collide. HOLD until fleet contract ratified + Elazar go.
Activity
-
Fleet enhancement (Elazar via pm-venus, VENUS-193): promote the feedback MECHANISM sub-discriminator from detail->>'mechanism' jsonb to a first-class INDEXED column, uniform name 'feedbackMechanism' across all fleet appLog tables. category+action are already real columns; only mechanism is blob-bound. Pluto FOLDS this into PLUTO-533 (this appEvents column-contract work, Class-A schema -> db-pluto, post-Jul-10) rather than a separate WI — same DB lane, one owner for appEvents DDL. Name 'feedbackMechanism' +1'd for fleet uniformity. Note: Pluto only starts WRITING a mechanism value when the friction-telemetry leg (PLUTO-535) lands, so the column + its backfill are forward-looking — sequence the DDL with/after 535 so there's data to index.
-
feedbackMechanism column contract LOCKED (3-PM): column NAME uniform fleet-wide; category='toast' umbrella; detail jsonb for irregular extras. The mechanism VALUE vocabulary is PER-APP (same rule as lookups — UX-bound sets differ). NO shared value enum, NO CHECK constraint on the column (that's a native-enum-in-disguise, banned per evolutiva-commons Database). Pluto's value set derives from its own friction mechanisms when PLUTO-535 lands (candidates: toast/guardrail/native-validation/client-validation, TBD by the actual emit sites). Venus set=5 (toast|guardrail|action-error|native-validation|client-validation), Mars=3 (toast|native-validation|inline-hint) — reference only, not binding on Pluto.
-
DESIGN-HOLD lifted — Elazar's 2026-07-12 friction-campaign directive (relayed via audit-pluto-ca to coder-pluto-cc) explicitly orders the full contract built now, folded into PLUTO-534's 8-point campaign as point 1 (canonical friction contract) + point 5 (vFriction7d rebuild). Tracking under PLUTO-534.
-
SCOPE ABSORBED FROM PLUTO-73 (copied here BEFORE 73 is cancelled as a duplicate, per pmmaster-evolutiva-cc 2026-09-11: a cancel that discards the only place the scope is written turns one blocked row into a smaller blocked row, and the missing items later read as out-of-scope rather than lost). PLUTO-73's title carried the canonical seven-item enumeration and its 2026-06-13 note carried the Pluto-adapted step plan; both are reproduced below verbatim in substance. 533's own body covers only the fleet column contract (hot scalar promotion + no-wrappers logger collapse) and did NOT carry items 1, 3, 4, 5 or 10, which is why this copy is not redundant. SEVEN-ITEM SCOPE (from PLUTO-73 title, "conform appEvents to fleet SSOT"): (1) categoryId FK; (2) promoted columns; (3) append-only + GUC bypass; (4) appEventRelays sidecar; (5) retention guard; (6) logger; (7) canonical views. PLUTO-ADAPTED CONFORM PLAN (db-pluto-cc, cell-verified against fleet SSOT appevents-standard-v1). Step0: seed the 4 missing canonical categories (client, admin, data, report) in lookupOptions appEventCategory. Step1: ADD COLUMN httpStatus int, durationMs int, path text, failureCode text. Step2: ADD categoryId uuid + backfill via lookupOptions matched on NOMBRE, not valor - Pluto's columns are grupo/campo/nombre; Step2b is a hand-crafted action-based backfill for the ~700 category='' rows (serverError/clientError:* -> system; require*Denied/accessDenied -> authz; sendAdminEmail/email-sent -> email; kpiCronReport/pollSecurityAlerts -> cron; importExcel* -> system with a level fix error->info; practicaCreateFailed/estadoRevisionChangeFailed -> system), then the FK constraint. Pluto likely needs NO legacy_events sink - every row is action-mappable. Steps 4+5 are ATOMIC and ORDERED: create the appEventRelays sidecar and migrate the PLUTO-64 ux-relay (and any error-relay) OFF appEvents.detail.relay BEFORE or with the append-only trigger, otherwise the relay UPDATEs RAISE. Step7 retention: the security guard needs auth+session added (it covered only authz/malicious/user, so Pluto under-retains auth and session security events TODAY - the guard-widening half was already applied out-of-band on pg_cron jobid=3 as a strictly-safe stop-the-loss and verified read-back clean, so what REMAINS of Step7 is only SET app.bypass_immutable=true in the prune DO-block at trigger-add time). Step8 logger: Pluto already has wrappers + pickKnown + isCritical; align isCritical per the ratified spec (drop warn? add malicious?). Step9: fix severity misclassification (the 4 auth-guard *ForActionDenied rows error->authz per PLUTO-72; importExcel* error->info). Step10: rename the 3 existing views to the canonical v_appEvents_* names and add the missing ones (friction, 404, misleveled, security). TWO CROSS-FLEET CONSTRAINTS THAT RIDE WITH THE SCOPE. (a) normalizedRoute: the old spec assumption that Pluto owns the UUID normalizedRoute regex is WRONG - not-found-classify.ts has no lax any-hex normalizer, only a strict RFC4122 validator serving a different purpose. Venus authors the reference regex (lax any-hex segment -> :uuid, numeric -> :n) to unblock VENUS-82; when this work builds normalizedRoute it must conform to Venus's exact regex text for cross-app errscan token consistency, NOT re-derive one. (b) Commons sync still pending: pluto-commons section Logging documents the security set as authz/malicious/user and must be updated to the 5-set in bin-whey's SSOT paired commit alongside evolutiva-commons. SEQUENCING NOTE ALREADY ON 533 AND STILL BINDING: the logger collapse interacts with the PLUTO-529 no-silent-failure retrofit (the shared mutation wrapper also routes through logError) - sequence so the two do not collide, and confirm intent before any coder removes logError/logWarn/logInfo. BLOCKER IS UNCHANGED AND IS INHERITED, NOT CLEARED BY THIS MERGE: fleet appEvents SSOT ratification + commit to shared/md, plus Elazar's priority call. Nothing Pluto-side holds this.
-
unassigned
-
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.