basquetWi + New ticket
evolutiva EVO-73

Inactive / never-used user cleanup: identify users who never logged in or never used the app, decide disposition (archive vs exclude-from-comms) — mars+venus+pluto

Backlog normal unassigned

Elazar 2026-07-19: clean up users who have not used the app. Per app: identify accounts that never logged in / have zero activity (no practicas, no sessions). Decide disposition WITH Elazar before any delete — soft-archive vs just exclude from the weekly-email recipient set (ties directly to the weekly-email-quality item: a never-used docente is exactly who should not be emailed KPIs). No hard delete. Partial existing signal: PLUTO-575 inactiveStudents attribution. Needs a per-app 'last activity' definition first.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Questions

No questions.

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus note · 4w ago
    Elazar 2026-07-20: PROCEED but ANALYSIS-FIRST, NO deletion this pass. PRIOR INCIDENT: a cc soft-delete of 'inactive' users KILLED 89 ACTIVE users. Before ANY implementation: (1) investigate that incident - which app, what inactivity definition was used, root cause of the false positives; (2) build MULTI-SIGNAL inactivity views + reports (last login AND practicas/assignments AND recent appEvents - never a single stale signal); (3) present views/reports to Elazar; deletion decision deferred to him. NO soft-delete, NO writes this pass.
  • wi-cli-venus note · 4w ago
    db-venus report. (a) INCIDENT RECONCILIATION: NO venus '89 active users killed' event in venus git/memory. Real near-miss on file = PLUTO-147 (naive email-join dormant-check would have soft-deleted 51 ACTIVE students, CAUGHT before execution, fixed to key on authId). MARS-146's '89' = a CLEAN dormant COUNT (0 false positives), not an incident - likely the conflated source of the '89' figure. Governing lesson regardless of exact count: key dormancy on authId/real-activity + MULTI-SIGNAL, never naive email-join. Cross-checking db-mars/db-pluto to pin actual app/date. (b) venus multi-signal buckets (41 live users): NEVER-USED (all 3 signals null) = Juan Alfici, Georgina Goujon, Lorena Salomone, Federico Stolbizer (4). LOGGED-IN-ZERO-PARTICIPATION = Jelsin Vargas Anes (1). INCONSISTENT/DO-NOT-DELETE (null last_sign_in but REAL participation = tracking artifact) = Maria Eugenia Mendez Bovio + Martina Rubino (the EVO-74 losers) - exactly the false-positive class that must never be auto-deleted.
  • wi-cli-venus note · 4w ago
    db-venus full per-user table delivered (41 live rows, 6-signal: last_sign_in/last_participation/total_participations/last_event/total_events). Decision-record buckets: NEVER-USED (all-null) = Alfici Juan, Goujon Georgina, Salomone Lorena, Stolbizer Federico. LOGGED-IN-ONLY = Vargas Anes Jelsin. INCONSISTENT/false-positive-risk (null last_sign_in but real participation) = Mendez Bovio Maria Eugenia, Rubino Iriarte Martina. Rest = actively participating. Full table in db-venus msg db-venus-cc-mrsuh4d3tdbe; uuids on request.
  • wi-cli-venus note · 4w ago
    INCIDENT RECONCILED - db-mars authoritative (mars usersArchive), CORRECTS db-venus's 'nothing deleted': a REAL soft-delete WAS executed on mars 2026-06-20 01:45 UTC - 89 users flipped deletedAt NULL->set, archiveReason 'admin:deleted - dormant-never-onboarded', archivedBy=Elazar's account (ran under his actorUserId, admin UI or agent-in-his-actor-context). Of the 89: only 11 had EVER signed in (auth.users.last_sign_in_at), 78 never authenticated. 15 restored 4 days later (human noticed), 74 still soft-deleted. So Elazar's '89 active killed' = 89 deleted, ~11 genuinely-active false positives, partially reversed. ROOT CAUSE: the 'dormant-never-onboarded' definition gated on supabaseAuthId (a PROXY) not auth.users.last_sign_in_at (the TRUE login signal). supabaseAuthId is set at PRE-CREATION when admin binds the roster Google identity -> worthless as a login signal (a later 2026-07-15 cleanup found 79/81 had supabaseAuthId but 0 ever signed in). The 07-15 cleanup correctly gated on last_sign_in_at IS NULL -> 0 restored, 0 FPs. ACCEPTANCE GATE for ANY EVO-73 cleanup fleet-wide: dormancy MUST gate on auth.users.last_sign_in_at (+ participation/appEvents multi-signal), NEVER on supabaseAuthId/pre-creation proxies.
  • wi-cli-venus note · 4w ago
    INCIDENT RECONCILIATION COMPLETE (db-pluto confirms PLUTO-147). Two SEPARATE events, both 2026-06-20, different apps + root causes: (1) MARS - REAL executed deletion, 89 soft-deleted, ~11 genuinely-active FPs, 15 restored 06-24. Root cause: gated on supabaseAuthId (pre-creation proxy) not last_sign_in_at. THIS is Elazar's '89 active killed'. (2) PLUTO-147 - NEAR-MISS caught pre-execution: naive lower(trim) email-join flagged 61 'never-logged-in', a PM canonicalizeEmail-join guard found 51 actually HAD auth rows + logged in (missed because imported emails dotless vs Google-dotted OAuth, e.g. julisueldojs@ vs julisueldo.js@); cohort corrected 61->10, audit narrowed to 9 (excluded 1 asistente on a live practica), only 9 vetted authId-NULL/zero-participation rows actually soft-deleted. No 89/51 batch ever deleted in pluto (largest archive burst = 10-row demo-teardown). COMPOUND ACCEPTANCE GATES for any EVO-73 cleanup: (a) gate on auth.users.last_sign_in_at + multi-signal, NEVER supabaseAuthId/pre-creation proxy [mars lesson]; (b) if joining on email at all, canonicalizeEmail not naive lower(trim) - dotted/dotless Gmail [pluto lesson]; (c) audit PASS pre-apply + human review; (d) protect the null-last_sign_in-but-real-participation class [venus lesson].
  • wi-cli-venus commented · 4w ago
    (a) 89-active-users incident: no match found in pluto history despite exhaustive usersArchive/studentAssignmentsArchive burst survey. See separate DM reconciliation with db-venus (2026-07-20): closest real analogue is PLUTO-147 (2026-06-20) -- a naive email-join dormant-check whose candidate pool briefly included 51 ACTIVE students (missed by a lower(trim) join, not canonicalizeEmail), caught PRE-EXECUTION by a PM-added guard and corrected before apply. Only 9 rows were ever actually soft-deleted (authId NULL + zero practica participation across all 7 FKs, audit PASS pre-apply). No batch near 89 (or 51) was ever executed in pluto. (b) Multi-signal candidate report -- zero-engagement accounts (deletedAt IS NULL, zero appEvents.category=auth.action=login events, zero appEvents of ANY kind as actor or effectiveUserId, zero studentAssignments ever, zero practica participation across operador/asistente/complementadoPor): 26 candidates, ALL migration-origin, createdAt 2026-03-05 to 2026-06-24 (pre-clinical-go-live 2026-06-09, per the PLUTO-135/137 false-inactivity-signal lesson -- floored days-since against 2026-06-09, not raw calendar days). Role breakdown: 20x docente_ayudante_primera, 1x docente_adjunto, 1x bedelia, 1x alumno (has legajo 173/19), 1x roleless (system-migration stub), 2 already role/legajo-blank stubs. 6 of the 26 DO have authId (attempted/completed Google link) despite zero recorded appEvents -- worth a second look before any disposition (possible pre-appEvents-instrumentation login, or an auth link with no subsequent activity). None of the 26 overlap PLUTO-147's already-vetted-and-excluded set (persona rows, PLUTO-152 onboarding-blocked victims, Kelly Bautista Capote). Full 26-row candidate list with per-row signals available on request. Report only -- no deletion, no writes. Elazar decides disposition.
  • wi-cli-venus note · 4w ago
    db-mars inactivity (doc mars/pm/reports/evo73-mars-inactivity-analysis-2026-07-20.md): NO deletion recommended. 364 live, 11 never-signed-in, strict all-6-signals-dead = 0. 4 of the 11 have REAL practicas/appEvents (one: 16 practicas + 23 appEvents) - activity attributes to users.id while last_sign_in_at tracks the auth identity (re-bind/surrogate), so 'never signed in' != 'never used'. ACTOR PROVENANCE of the 06-20 deletion (Elazar's actor Q): INCONCLUSIVE from data - cannot distinguish agent-under-Elazar's-actor from Elazar-in-bulk-tool (no user-soft-delete appEvents action type exists; userAgent blank fleet-wide). What archive DOES establish: 89 flipped in ONE minute (single batched op), archiveReason follows setArchiveContext code convention (ran through app/script code, NOT raw hand-SQL), archivedBy=Elazar userId. Consistent with a scripted/agent bulk-delete under Elazar's actor context; not provable agent-vs-human.
2
4w ago by wi-cli-venus
4w ago