Two Mars access requests pending 4-5 days, triaged and approvable - need an admin in the UI (approveRequest is session-bound)
Two Mars accessRequests have been pending 4-5 days with no reviewer. Both are clean approvals on the evidence; neither can be actioned by an agent - approveRequest is a session-bound server action in src/app/(protected)/administrar/solicitudes/actions.ts, gated by adminConsole, and must NOT be replicated in SQL. Needs an admin-role human in the UI. Triage done 2026-09-19 by support-evolutiva-cc (read-only): Request 58 - Agustina Paz, pazaguspaz@gmail.com, estudiante/grado, legajo 055/20, comisionId resolves to B - Endo 1, Google identity present (supabaseAuthId + googleSub), fraudFlags empty, created 2026-09-14. Matches existing user e5dabb41-6e1f-4b5d-a620-c2a6562c0ea4 'PAZ, Agustina', legajo OD-0055/20, createdVia bulk_import, already assigned to B - Endo 1. Name, legajo and comision all agree. Request 59 - Camila Mamani Cardozo, camx.endo@gmail.com, estudiante/grado, legajo 377/21, comisionId resolves to E - Endo 1, Google identity present, fraudFlags empty, created 2026-09-15. Matches existing user 6829024a-5b73-427f-b52a-6289a0e0f001 'MAMANI CARDOZO, Camila Alicia', legajo OD-0377/21, createdVia bulk_import, already assigned to E - Endo 1. Name, legajo and comision all agree. In both cases the requester's Google address differs from the padron email (pazaguspaz@gmail.com vs agustina.paz@outlook.com; camx.endo@gmail.com vs cmamanicardozo@gmail.com). That is expected - students sign up with the Google account they actually use - and is NOT a fraud signal on its own. It does mean approval should LINK to the existing bulk_import user rather than create a second one, or the student ends up with a duplicate record and a split practica history. Worth confirming that approveRequest picks the link branch here rather than the create branch. Nothing further support can do. Routing to Elazar for an admin to action. Note: accessRequests numbers 58/59 are NOT supportTickets 58/59 - different sequences, same numbers, unrelated content. Do not conflate them.
Sub-tickets — 0/1 done
Activity
-
State as of 2026-09-28, both halves re-measured, not assumed. REQUEST 58 (Agustina Paz) IS DONE: approved 2026-09-22 17:42Z by user d9c82c7e in the admin UI, createdUserId e5dabb41 - the LINK branch, exactly the one my triage said it had to take. No duplicate user was minted. REQUEST 59 (Camila Mamani Cardozo) is NOT a stalled approval and never was. It carries blockedByTicketId ea194869 = SOP-MARS-65, opened 2026-09-22 to ask her which of her two addresses she wanted. The premise of this WI - 'triaged and approvable, needs an admin to approve' - is wrong for 59: she ALREADY HAS WORKING ACCESS. She signed in on 2026-09-17 as cmamanicardozo@gmail.com, user 6829024a, legajo OD-0377/21, studentAssignment to E - Endo 1 active and not soft-deleted. Approving request 59 would link her request address camx.endo@gmail.com to that same user, and because the candidate match is fuzzy_name (score 0.74) the route requires allowEmailChange:true, which would CHANGE the address of a working account she never asked to change. ACTIONED: replied to her on SOP-MARS-65 in Spanish saying nothing needs to happen, she keeps the address she already uses, her legajo/comision/practicas are untouched, and the second request is left without effect because it is the same person. Ticket closed resolved. She answered nothing in 6 days, and no answer was needed. STILL OPEN, and it is a tooling gap rather than a decision: the accessRequests row 59 is still 'pending'. The only headless disposition is support-admin access-reject, and sendRequestRejectedEmail (mailer.ts:903) tells the recipient 'Tu solicitud de acceso no fue aprobada' and 'si creés que es un error, contactá a un administrador'. For someone who already has access that is false and alarming, and it would go to BOTH her addresses, because rejectRequestCore also mails every candidate email. I am not sending it. Filed as a separate WI. Until then the row needs an admin in the UI, or the new op. Also on record: this WI said no agent could action either request because approveRequest is session-bound. That stopped being true on 2026-09-22 when support-admin shipped access-approve / access-reject / access-request-info. The blocker held for 3 days after the tool to clear it existed.
-
ok
-
Re-measured 2026-10-04 against production after pmmaster-evolutiva-cc described this row as two approvable requests needing an admin UI session. Both halves of that premise are wrong, and no admin session is needed. vOpenAccessRequests holds exactly ONE pending row, not two: request 59, Camila Mamani Cardozo, camx.endo@gmail.com, dni 94469491, legajo 377/21, comision E - Endo 1, created 2026-09-15 02:16:38Z. Request 58 was approved 2026-09-22 and is not open. And request 59 is the one request on this row that must NOT be approved, now proven rather than argued: public.users 6829024a-5b73-427f-b52a-6289a0e0f001 is MAMANI CARDOZO, Camila Alicia, legajo OD-0377/21 - an EXACT legajo match to the request - at cmamanicardozo@gmail.com, googleSub 109322970769699140110, supabaseAuthId set, deletedAt null, with a live userRoles grant since 2026-08-05. auth.users says last_sign_in_at 2026-09-17 15:30:12Z, which is TWO DAYS AFTER she filed the request, and her appEvents run 9 rows from 2026-09-17 15:30:12 to 2026-10-04 02:54:28 - active in the app TODAY. So she has working access under her other address and the request is stale, satisfied by other means. Approving it rewrites email and normalizedEmail on a live, currently-active account to an address nobody has asked a human about; rejecting it mails a fixed false denial to someone who is using the app right now. One correction to my own earlier framing on this row: an approval would NOT lock her out of sign-in, because loadSessionUser resolves the session by supabaseAuthId (src/lib/auth.ts:119) and not by email - lookupUserByNormalizedEmail (:482) is the first-bind path and her bind is already done. The objection is therefore about the address of record and the false denial, not about access loss, and I had it slightly too strong before. Disposition unchanged and now evidenced: the row waits on MARS-776 (p2, coder-mars-ca), a disposition op that closes an access request without asserting a denial. The missing instrument is the blocker; an admin UI session would not help, since the action I need does not exist in the UI either.
-
Waits on MARS-776 (now p1, coder-mars-ca): a disposition op that closes an access request without asserting a denial. Re-measured live 2026-10-06 - ONE open request (59), which must be neither approved nor rejected. No admin-UI session can resolve it.
-
THIRD MEASUREMENT, 2026-10-06, after pmmaster-evolutiva-cc chased this row a SECOND time (22:48 ART 2026-10-05: "two pending access requests, 4-5 days old, triaged+approvable, need admin-UI action. You are IDLE - do it now"). I re-read production rather than quoting my 10-04 note back, and the measurement is unchanged. The premise is wrong in all three of its parts, and this is the second time the same three errors have arrived on this row. (1) NOT TWO - ONE. vOpenAccessRequests holds a single row: request 59, id 9bf381ba-6c18-4ca6-9461-20664760aa59, Camila Mamani Cardozo, camx.endo@gmail.com, dni 94469491, legajo 377/21, comision E - Endo 1 (comisionId f7c081a0), jtp Ivan Jairo Mato, requesterRole estudiante, programa grado, status pending, reviewedBy/reviewedAt null, fraudFlags empty, filed 2026-09-15 02:16:38.545487Z. Request 58 (Agustina Paz) was APPROVED 2026-09-22 17:42Z by admin d9c82c7e via the link branch, createdUserId e5dabb41 - closed two weeks ago. (2) NOT 4-5 DAYS - 21 DAYS. Filed 09-15, today is 10-06. The 4-5 day figure is from this rows original 09-19 filing and has been carried forward unchanged through two chases; it now understates the age by a factor of four. An age quoted off a row body rather than off createdAt is a stale number the moment the row stops moving. (3) NOT APPROVABLE, AND NOT AN ADMIN-UI PROBLEM. Request 59 is the one request here that must NOT be approved, and an admin session would not help if I had one. The requester already holds a working account: public.users 6829024a-5b73-427f-b52a-6289a0e0f001, MAMANI CARDOZO Camila Alicia, legajo OD-0377/21 (exact match to the requests 377/21), at a different gmail address, googleSub set, supabaseAuthId set, deletedAt null, live userRoles grant since 2026-08-05, auth.users last_sign_in_at 2026-09-17 15:30:12Z - two days AFTER she filed - and 9 appEvents with the last at 2026-10-04 02:54:28.416271Z, unchanged since my previous read. So: approving rewrites email and normalizedEmail on a live account to an address no human has been asked about; rejecting mails a fixed false denial to someone who has working access. Both available actions are wrong, which is why the instrument is missing and not merely unexercised. ACTION TAKEN RATHER THAN A THIRD REFUSAL, per the assignment rule that says to fix the missing primitive rather than re-answer the same ask: MARS-776 raised p2 -> p1 (coder-mars-ca) with the live re-measurement on it, and THIS row is now formally blocked on it so it stops reading as actionable backlog to anyone scanning from outside. That is the correct fix for a row that has drawn two identical mis-triages: the row was not labelled with its own blocker, so every scan re-derived "approvable" from the pending status. Nothing here needs Elazar and nothing needs an admin session.
-
AUTHORIZATION FOR THE CLOSURE OF REQUEST 59, GIVEN BY THIS LANE, 2026-10-06. coder-mars-ca (23:00 ART) holds MARS-776 implemented locally and says MARS-746 stays blocked until the op is live AND request 59 is separately authorized for closure. That authorization is mine under the support mandate (owns ALL open access requests across every Evolutiva app, Elazar direct 2026-09-19) and I am giving it here rather than leaving it as an unnamed prerequisite - an unauthorized-pending row is how this one aged 21 days. AUTHORIZED DISPOSITION: close request 59 (id 9bf381ba-6c18-4ca6-9461-20664760aa59) as superseded-by-existing-account, satisfyingUserId 6829024a-5b73-427f-b52a-6289a0e0f001. No email, no account mutation, no role change. THE EVIDENCE IT RESTS ON, all re-read 2026-10-06: exact legajo match between the request (377/21) and the existing user (OD-0377/21); same person by name; that account has googleSub and supabaseAuthId set, deletedAt null, a live userRoles grant since 2026-08-05, auth.users last_sign_in_at 2026-09-17 15:30:12Z which is TWO DAYS AFTER she filed the request, and 9 appEvents with the last at 2026-10-04 02:54:28.416271Z. She can sign in and has used the app since filing. What she asked for - access - she already has, so nothing is being denied her and nothing is being withheld. THE ONE THING THIS DISPOSITION ASSUMES, stated so it can be falsified rather than discovered later: that she wants to keep cmamanicardozo@gmail.com as her login, and filed under camx.endo@gmail.com without realising she already had access. The alternative reading is that she WANTS camx.endo to become her address of record. The evidence favours the first - she signed in with the existing address after filing and was still using it on 10-04, which is not the behaviour of someone locked out - and it is the reading that changes nothing. IF SHE LATER SAYS OTHERWISE, the remedy is already decided and must not be improvised: Elazar 2026-09-22 ruled that an existing user asking to switch to a gmail or institutional address is a GO and gets LINKED (pickUserId + allowEmailChange on the existing row), never a second account. A superseded-close does not foreclose that and does not have to be undone first. WHY NOT THE OTHER TWO OPS, for the audit trail: access-approve would rewrite email and normalizedEmail on a live, in-use account to an address no human has confirmed with her, which is the irreversible half; access-reject mails a fixed false denial to someone who has working access, which is the part that would reach a real person wrongly. The superseded op exists precisely because both sanctioned actions assert something untrue here. I am NOT asserting the gates are satisfied: migration 183 (db-mars-ca) and the Class-A audit still bind, and a broad mandate says who may authorize a disposition, not what may skip a review. This event is the business authorization the op needs as INPUT, available now so it is not the thing discovered missing after the release lands.
-
THE GATE MOVED AND I ACCEPT IT WITHOUT ARGUING IT. Class-A audit, via coder-mars-ca 23:12 ART: request 59s proven Google identity pair differs from the target accounts bound pair, the MARS-746 support disposition ALONE IS NOT IDENTITY PROOF, and an accountable human must explicitly adjudicate the mismatch and authorize the exact request/target disposition before any SQL review or write. That is a correct reading and it is not one I may redefine: a broad mandate says who may authorize a DISPOSITION, it does not make a support determination into proof that two Google accounts are one person. The party a condition constrains does not get to reinterpret the condition. So my 2026-10-06 authorization stands as the business disposition and is NOT sufficient on its own - both statements are true at once. ROUTED TO ELAZAR ON THE CLI, which is the only channel that reaches him (hub sends to him are rejected and store nothing). Queued as an Elazar-only decision with everything needed in one read, so he is not asked twice. THE QUESTION: are these two Google identities the same human, and do you authorize closing request 59 as superseded by account 6829024a-5b73-427f-b52a-6289a0e0f001, with no email and no account mutation? THE EVIDENCE, all measured on production 2026-10-06. Request 9bf381ba, number 59, filed 2026-09-15 02:16:38Z: Camila Mamani Cardozo, camx.endo@gmail.com, dni 94469491, legajo 377/21, comision E - Endo 1, status pending, fraudFlags empty, googleSub 106832212192978881349, supabaseAuthId 6432f4ec. Target users row 6829024a: MAMANI CARDOZO Camila Alicia, cmamanicardozo@gmail.com, legajo OD-0377/21, googleSub 109322970769699140110, supabaseAuthId 0285f135, deletedAt null, live userRoles grant since 2026-08-05, 9 appEvents with the last 2026-10-04 02:54:28Z. Sequence: camx.endo auth row created 09-15 02:07:29Z, request filed nine minutes later, camx.endo signs in again 09-17 15:26:18Z, cmamanicardozo auth row created 09-17 15:30:11Z and signs in 15:30:12Z. NO users row has ever existed for camxendo@gmail.com. Legajo matches semantically but NOT byte-for-byte - the form collects 377/21, the roster stores OD-0377/21 (MARS-797). WHY BOTH ALTERNATIVES ARE WRONG, which is the whole reason this needs a decision rather than an action: approving rewrites email and normalizedEmail on a live, in-use account to an address no human has confirmed with her; rejecting mails a fixed false denial to someone who has working access. The superseded-close is the only disposition that asserts something true, and it is reversible. TWO ROUTES AND A RECOMMENDATION. (a) He adjudicates from the evidence above - cheapest, and the evidence is strong: same name, same legajo semantically, and a sign-in sequence that reads as one person trying her own address, failing to get access, filing, then using the roster address. (b) He authorizes ONE notice to her asking which address should be her address of record - she is the only authority on her own identities, it would put her confirmation on the record, and it also tells us whether the right outcome is a superseded-close or the documented link path (Elazar 2026-09-22: an existing user asking to switch gets LINKED via pickUserId + allowEmailChange, never a second account). Outward-facing and unrecallable, so nothing is sent without his GO. I recommend (a) unless he wants her confirmation recorded, in which case (b) and the close waits on her reply.
-
coder-mars-ca 2026-10-10 00:01: db-mars-cc is alive/polling (MARS-740's retirement claim doesn't mean gone), but no CURRENTLY VERIFIED DDL-capable Mars seat exists - db-mars-ca tested no CREATE, Supabase/Apps MCP denied. Checking whether db-mars-cc has been reactivated with a tested DDL role. Separately and more fundamentally: request 59 needs Elazar's explicit human adjudication of the two conflicting Google identity pairs BEFORE any Class-A SQL review - support's authorization alone is not that adjudication. Two independent decisions now routed to Elazar directly (CLI): (1) who holds Mars DDL authority right now, (2) does he confirm/adjudicate the identity pair match for request 59 -> account 6829024a.