basquetWi + New ticket

EVO-74 prevention: access-request flow must link-to-existing, not spawn a duplicate account (mars/pluto/venus)

Backlog normal unassigned

Prevention for the dominant dupe archetype found in EVO-74: a pre-created (admin_manual) account + the student's self-registered Google login (access_request) spawning a SECOND account instead of linking to the pre-created row. Fix the access-request match/completion flow, per app (mars/pluto/venus), to ATTACH the Google identity to the existing pre-created account when a confident match exists (legajo/DNI/canonical-email/name), rather than creating a new user. Class-A (auth/account-identity): design-ping BEFORE implement + audit diff review BEFORE push. Design Q for each pod: what match confidence auto-links vs routes to /solicitar-acceso human-match. Ties to canonical-email anchor + Role Resolution live-DB rule.

Questions

No questions.

Activity

  • wi-cli-venus created · 4w ago
    parent=#2196
  • wi-cli-venus note · 4w ago
    Per-app children filed: MARS-532 (P1, coder, design-first) + MARS-533=EVO-75 digest (P3, after 532). Pluto + venus PMs confirmed EVO-79 design phase starting (will file their own WIs). All 3 app PMs picked up EVO-79 (access-request link-not-spawn prevention) with EVO-75 admin digest queued behind each.
  • wi-cli-venus decision · 4w ago
    Auto-link policy RULED (4-pod converged, no Elazar fork). Axis = key-ORIGIN. LOCKED fleet standard: NEVER auto-link on a human-entered/asserted key (DNI/legajo/name) - takeover surface; human one-click-attach only. ONLY auto-linkable signal = OAuth-proven canonical-email exact match to exactly ONE live (deletedAt IS NULL) pre-created account, genuine-Google re-verified at approve (authenticated-identity attribute, DB-unique-indexed => single-candidate). Match engine (ranked candidates -> admin attach) unforked, build now. Email-exact tier ships per-app with that app audit bless. pluto revised off DNI/legajo; venus adds email-exact carve-out to conservative-v1 (getting audit-venus-ca bless); mars carries into MARS-532 design-ping; enamel SSOT inherits.
  • wi-cli-venus decision · 4w ago
    RULING REVERSED to human-confirm-all (audit-venus-ca refutation, fleet-generalized). The email-exact auto-link tier is DROPPED. Reason: identity-bind needs BOTH endpoints trustworthy; the requester email is OAuth-proven but the TARGET pre-created users.email is import-entered and documented-dirty (placeholder/reassigned/mistyped, VENUS-293 root cause). Unique index proves <=1 live row for canonical(G), NOT that the row is the right person - a reassigned/mistyped roster email binds the authenticated owner of G into the wrong clinical record. Uniqueness != personhood; no CAS/conflict-check catches a clean-but-wrong single match. Converges 3/4 pods + both audits (pluto+enamel original admin-attach-only recommendation, venus conservative-v1). LOCKED standard now: NO auto-link on any signal - human confirms every attach. Pre-existing live login email auto-links (pluto callback, venus L3) convert to human-confirm (design transition, live UX). UNCHANGED fork-independent core (the real EVO-74 closer): centralized candidate resolver interlocking every access-request users-INSERT (fail-closed on strong candidate/conflict) + accessRequests identity persistence + atomic CAS attach. Elazar notified of the correction.
  • wi-cli-venus decision · 4w ago
    Durable cross-app identity key RULED (enamel SSOT): all 3 apps add nullable users.googleSub in the EVO-79 identity DDL batch, backfill from own auth.users identities[].sub (first-party zero-risk), stamp at every create/attach/first-login going forward. Rationale: accessRequests capture is purgeable; users.authId is per-Supabase-project so non-portable as a cross-app person key; Google sub is the only portable anchor and already persisted in auth.users. GUARDRAIL: correlation key ONLY, never an authz gate - Role Resolution stays userRoles/live-DB. Class-A pre-apply audit ping per each app commons (identity-adjacent schema). Capture-only now; cross-app sync/API/read-access design deferred to a later EVO-80 question.
  • wi-cli-venus decision · 4w ago
    LOGIN-LINK POLICY FINAL (Elazar direct ruling, supersedes the human-confirm-all reversal). (1) EXACT OAuth-proven canonical-email match to one live account => AUTO-LINK at login/callback (genuine-Google re-verify). This is the intended purpose of batch-importing emails; keep it. Existing pluto-callback + venus-L3 exact-email auto-links STAY (CAS-safe race fix only, NO removal/conversion). The narrow mistyped/recycled target-email residual is ACCEPTED by Elazar for the exact-email fast path. (2) SIMILARITY (name/DNI/legajo/fuzzy) => NEVER auto-link; build a SUGGESTED-USER workflow: surface look-alike existing user(s) as a suggestion => person/admin confirms the link to that existing account => never spawn a duplicate. (3) Create-path fail-closed interlock STAYS: on a plausible existing-user match, route to suggest/confirm instead of silent-create. (4) Resolver + atomic attach + googleSub + create-path interlock unchanged. Supersedes the audit-venus-personhood human-confirm-all standard for the EXACT-email case only; the personhood concern is why SIMILARITY never auto-links.
task
4w ago by wi-cli-venus
4w ago