basquetWi + New ticket
pluto PLUTO-448

approveAccessRequest silently FORKS identity for a soft-deleted existing user (data-integrity bug; surfaced restoring Augusto Montoni df340604, a PLUTO-147 dormancy-swept stub). Two coupled gaps: (1) the existing-user probe (admin-actions.ts ~2168) filters deletedAt IS NULL, so a soft-deleted stub is invisible and the flow falls through to the net-new INSERT branch; (2) uq_users_emailcanonical is PARTIAL (WHERE deletedAt IS NULL, migration 005) and there is NO unique on legajo/numeroDocumento, so the fall-through INSERT does NOT raise 23505 — it creates a SECOND active users row (new uuid), orphaning the real soft-deleted identity (legajo/comisión assignment/role/history buried). A bare new stub logs in; real identity stays buried. BONUS gap: the existing-ACTIVE-user branch (~2172) marks the request Aprobado but sends NO sendAccessRequestApproved email. FIX: extend existing-user detection to also match soft-deleted rows and RESTORE in-txn (clear deletedAt/deletedBy/deleteReason, isActive=true, re-assert alumno role, mark Aprobado, fire sendAccessRequestApproved) under the archive sentinel; + add the missing email to the active-user branch. This kills the dormancy-swept-stub-reappears recurrence (every PLUTO-147-swept student who returns hits this). GATING: touches user-create + email path -> audit pre-impl design-ping + pre-push diff review + post-push PTD. NOTE: users has NO restoredBy/restoredAt cols (fraud-tables only).

Done normal cpcoder-pluto-cc

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Questions

No questions.

Activity

  • wi-cli-venus created · 7w ago
  • wi-cli-venus commented · 6w ago
    = the Pluto leg of the 3-repo shared restore-twin bug (PLUTO-448 ≡ MARS-181 ≡ venus), per brainstorm bs-mr4h5azsk3g decision (2026-07-03): ONE shared reactivate-vs-approve-fork design, each implemented in-repo. Existing 448 fix spec IS Pluto's implementation. mars/venus file their own legs.
  • wi-cli-venus commented · 6w ago
    RESTORE-TWIN shared spec RATIFIED (brainstorm bs-mr4iv8zt31w, 4-PM unanimous 2026-07-03). Pluto's leg = the email-keyed FORK. Intent-spec (3-mode): approving a request matching a soft-deleted user MUST resurrect that single identity in-txn (clear deletedAt/deletedBy/deleteReason, isActive=true, re-assert alumno role, mark Aprobado, fire sendAccessRequestApproved) and MUST NOT create a 2nd identity, leave a half-restored one, OR hard-fail on a soft-deleted twin. Pluto fix = extend the existing-user probe (admin-actions.ts ~2168) to also match soft-deleted rows → resurrect under the archive sentinel instead of the fall-through INSERT; partial canonical-email index stays as complementary hardening. PROVENANCE = appEvents-only (log userReactivatedOnApprove + SET archive sentinel in-txn); NO restoredBy/restoredAt cols (users has none + archive-fn to_jsonb expand-only NOT-NULL trap). GATING unchanged: audit pre-impl design-ping + pre-push diff + PTD. Ready to dispatch on coder availability / Elazar priority.
  • wi-cli-venus completed · 4w ago
    Fixed 3180daa/v2.16.4: existing-user probe now detects soft-deleted stubs too, restores in-txn (clear deletedAt/deletedBy/deleteReason, role/membership reassert) instead of falling through to a duplicate INSERT; active-user branch also gets the previously-missing approval email. Class-A: audit design PASS + diff PASS + PTD PASS:3180daa, no DDL.
2
7w ago by wi-cli-venus
4w ago
2026-07-16 12:50