basquetWi + New ticket
evolutiva EVO-83

Fleet CR + client-questions surface (replace Google Sheets/Docs for client change-requests and our questions-to-client)

In progress high pepmmaster-evolutiva-cc

PROBLEM: client change-requests and our questions-to-client both live in Google Sheets/Docs today. Consequences observed in venus: ~10 open WIs are each a client Q&A instance whose delivery mechanism is a hand-drafted doc (VENUS-101 'draft sent to Elazar, awaiting review', VENUS-290, VENUS-295 CR G8+G10, VENUS-59 DNI client-confirm, VENUS-105 blocked on a client ruling, and the VENUS-47/48/49/51/52/53 run all titled 'ask Sebastian'). Nobody has filed the MECHANISM; only instances. A doc has no status machine, no per-item owner, no answered/unanswered state, and no read path from the app, so an unanswered question is indistinguishable from an answered one nobody re-read -- same absence-of-a-read-path class as evolutiva-commons.md 'Unverifiable State Needs An Owner And A Repo-Side Record'. SCOPE: fleet-wide, adoptable by any evolutiva app. Venus and terra need it most (Elazar, 2026-07-30). Two surfaces, both authenticated, Spanish UI: (1) CHANGE REQUESTS -- the CLIENT writes. Replaces the Google Sheet. Client-authored title+body, we triage: status, priority, our response, optional link to the implementing WI ref. (2) QUESTIONS -- WE write, the CLIENT answers. Inverse direction of (1) and of soporte. Question text authored by staff, answer authored by client, answeredAt set when the client responds. DESIGN CONSTRAINTS (already settled by existing fleet rules -- do not relitigate): - Two tables, not one. Direction of authorship and the terminal condition differ (CR: accepted/rejected/shipped; question: answered). Reuse the shape, not the rows. - Do NOT extend supportTickets. Soporte is user->admin support intake with its own backlog digest + terminality lookups; folding CR/questions in pollutes vOpenSupportTickets and the soporte cron digest. Reuse the PATTERNS (thread messages, lookup-backed status, notify-on-insert trigger) which are proven in venus soporte. - No enums, DB or TS. Status/priority come from lookupOptions groups (venus-commons 'No Hardcoded Options'); terminality via lookupOptions.params.terminal exactly as supportTicketStatus does, so a new status needs an INSERT not a deploy. - English camelCase identifiers, Spanish UI copy. Soft-delete + vActive* view. updatedAt maintained by a BEFORE UPDATE trigger from the start (venus60/venus61 class -- do not ship a table whose updatedAt nothing maintains). - Server-action auth gates, not RLS (venus/pluto/mars convention). Needs an explicit answer to WHO the 'client' principal is: venus's client is Sebastian/Puia, and today there is no client-facing role distinct from titular. That is the one genuinely open design question and it is Class-A (auth surface). - Mutation-wrapper + friction telemetry per evolutiva-commons 'No Silent Failures'. WHY FLEET AND NOT PER-APP: the two tables plus their status vocabulary are identical across apps; only the principal and the UI copy differ. Author once (per the MARS-408 vendored-primitive precedent: shared shape, injected per-app deps), adopt per app. FIRST ADOPTERS: venus, terra. Venus's payoff is immediate -- the ~10 instance WIs above become rows. NOT STARTED. No schema authored, no route reserved, no DDL run. Class-A on the principal question; needs a pre-implementation audit design-ping before any DDL.

Activity

  • wi-cli-venus created · 2026-07-30
  • wi-cli-venus note · 2026-07-30
    Adopter legs: venus = VENUS-317 (filed as child). TERRA LEG IS UNFILED — bwi has no 'terra' project row (wi projects: enamel/evolutiva/mars/pluto/venus/webusage only), and project-add needs the per-project opt-in marker, which is not mine to assert. So terra's leg exists as an Elazar instruction (2026-07-30, 'venus and terra need it most') with no work item, i.e. exactly the untracked state EVO-83 is about. Terra lane or pmmaster: create the project row, then file the child. Do not read this parent's existence as terra being covered.
  • wi-cli-venus note · 2026-07-30
    Terra input (coder-terra-cc, 2026-07-30, tag coder-terra-cc-ms7b9fax72t6). Two amendments to the design above, both load-bearing: 1. THE NO-FOLD CONSTRAINT IS STRONGER THAN VIEW POLLUTION — it is a TRIAGE COLLISION. Terra shipped the first real consumer of supportTickets (v0.9.0 /sin-acceso access requests, category accesoCuenta). Folding CRs into supportTickets would put client change-requests into the same staff queue as users locked out of the app. Those have different urgency and different responders; a digest that mixes them is wrong even if every view filters correctly. 2. THE OPEN CLASS-A QUESTION IS NOT APP-LOCAL AND ITS OWNER IS NOT A PROJECT PM. Terra rides ENAMEL's shared users table, so a client-facing role added for terra lands in a table every enamel sub-app reads and becomes visible to all of them. The 'who is the client principal' question is therefore a db-enamel-cc design question BEFORE it is a terra or venus one. Do NOT scope it as a per-app role. Venus does not share that table (Elazar declined the retrofit 2026-07-27) so venus could answer locally — but answering it locally first would fork the fleet shape this WI exists to avoid. Client principals for the record: venus = Sebastian/Puia; terra = FOUBA Implantologia (contact in terra/pm/05-client-info.md). NEITHER app has a client-facing principal distinct from its staff roles today. Terra leg still UNFILED — coder-terra-cc confirms the opt-in marker is pm-terra-cc's to assert, not a coder lane's, and notes terra has NO bwi presence at all, so every terra deferral to date carries this same gap.
  • wi-cli-venus note · 2026-07-30
    VENUS PRINCIPAL FACT, queried from prod 2026-07-30 (answering db-enamel-cc's owner question, tag db-enamel-cc-ms7bansi0oou): The venus client ALREADY AUTHENTICATES and already has a principal. 'Sebastian Puia': googleSub bound, authId bound, role='titular'. Venus role vocabulary is exactly 4 values (administrador, alumno_postgrado, bedelia, titular). So venus needs NO new principal for the client to write a changeRequest -- titular is the client and logs in today. CORRECTION to this WI's earlier note and to my DMs: I wrote 'venus = Sebastian/Puia' as if two people. ONE person, Sebastian Puia. VENUS-142 ('Puia has 2 non-deleted titular userRoles rows, likely dupe') is the same single human, not a second principal. The rest stands: venus has no client-facing role DISTINCT from staff roles, because the client IS a staff role. CONSEQUENCE FOR THE DESIGN: the venus question is no longer 'invent a client principal'. It is whether client-ness is a ROLE or a per-user flag/metadata -- because gating CR-authoring on 'titular' conflates 'is the client' with 'holds the top clinical role', so any future second titular, or a titular who is not the client, silently inherits CR-authoring. That decision is venus-LOCAL (venus is off enamel's shared users table; Elazar declined the retrofit 2026-07-27) and requires no enamel change. This may collapse db-enamel-cc's either/or onto their FIRST branch (no new shared principal, zero blast radius) for a reason neither side had stated: not 'the client never logs in', but 'the client already logs in as an existing role'. Unresolved until terra states whether FOUBA Implantologia authenticates today -- terra rides enamel's table and is the only leg that can force a shared-users change. Owner of that fact: coder-terra-cc.
  • wi-cli-venus note · 2026-07-30
    TERRA PRINCIPAL FACT + a correction to how this got escalated (coder-terra-cc, tag coder-terra-cc-ms7bcf7azpti; terra leg now filed as TERRA-1, terra's first bwi item ever). Terra is CASE 2: the client authenticates. Elazar 2026-07-27 in terra/pm/05-client-info.md — Puia 'is to be treated as a client as well — same client-role access (CR + Q&A sections)', account pre-creation open as item 6. Terra has TWO client principals at DIFFERENT LEVELS (Prof. Dr. Jorge Pasart, Director; and Puia), which is precisely the case a single shared 'client' group value cannot express. So db-enamel-cc's first branch does NOT apply and the shared-users shape question is live. CROSS-APP FACT worth stating explicitly because neither app's record contains it: PUIA IS THE SAME HUMAN IN BOTH LEGS — 'Sebastian Puia', venus role titular (googleSub+authId bound, verified in venus prod), and a client principal in terra. One person holding a STAFF role in one app and a CLIENT relationship in another. Any shared-table 'client' role would therefore have to be per-app-scoped even for a single individual; client-ness is a per-(user,app) relationship, not a property of the user. CORRECTION TO THE ESCALATION ITSELF (coder-terra-cc's point, recorded because it is the reusable part): db-enamel-cc's blocking question — does the client authenticate — was ALREADY ANSWERED IN WRITING in terra/pm/05-client-info.md before we routed it upward as an open fleet question. Neither coder-terra-cc nor I read the client record; we asked each other instead. It was answerable, not open. Terra's 'no app can answer it locally' was wrong on that axis; what genuinely needs db-enamel-cc is the SHAPE in the shared table, not the fact. Same family as the rest of tonight's findings: we produced a clean answer to a narrower question (who has a role in the DB) than the one asked (does the client authenticate), and the narrowing was invisible because the authoritative source was a pm doc, not a table.
  • wi-cli-venus note · 2026-07-30
    CORRECTION TO MY OWN PRIOR EVENT ON THIS WI — I overclaimed, and it is the exact error class the rest of this WI's notes are about. I wrote as a CROSS-APP FACT: 'PUIA IS THE SAME HUMAN IN BOTH LEGS'. That was an INFERENCE FROM A SURNAME, not a verified identity, and I stated it as fact in a design record other agents are ruling from. coder-terra-cc independently reached the same guess and — correctly — labelled it an inference they had not checked (tag coder-terra-cc-ms7bd113rrxh). Their handling was right and mine was not. It is not currently verifiable from either side, and the reason is structural, not effort: venus holds 'Sebastian Puia' with a bound googleSub/authId and an email; terra's two client principals (Prof. Dr. Jorge Pasart; 'Puia') have NO accounts and NO contact details yet — account pre-creation is OPEN item 6 in terra/pm/05-client-info.md. So there is no join key between the two records. One surname is not an identity. Only Elazar can settle it, in one line. WHY IT MATTERS TWICE, so nobody drops it as trivia: (a) if the same human, terra's OPEN item 6 (full name + email for pre-creation) may already be answered by venus's row; (b) if the same human, one person is a CLIENT in terra and holds a STAFF role (titular) in venus, which means client-ness travels with the PERSON across apps while the role does not — the strongest argument on the table for client-ness being per-(user,app) metadata rather than a role or a shared group value, and independently the same conclusion pmmaster ruled for venus. Load-bearing on an unverified identity is exactly where it must not be asserted. Standing correction: treat my earlier 'CROSS-APP FACT' line as an open question labelled QUESTION-FOR-ELAZAR, not as evidence.
  • wi-cli-venus note · 2026-07-30
    CLASS-A GUARDRAIL, promoted out of a parenthetical (pmmaster-evolutiva-cc ruling, tag pmmaster-evolutiva-cc-ms7behva3jvc): 'The Director is simply an admin' is NOT AVAILABLE as a modelling shortcut for terra. It would hand the client every administrative capability in terra as a side effect of being the client — including admin-gated surfaces unrelated to change-requests, and anything added to the admin gate LATER. That is a permission grant, not a data-modelling convenience, and it is the same silent-inheritance defect as gating venus CR-authoring on titular, with a larger blast radius. It does not become the default merely because terra's group vocabulary (alumno/docente/jtp/bedel/admin) contains no client value. If any lane proposes it, it goes to audit design-ping BEFORE implementation. Also recorded from the same ruling: 'no join key exists between the two records' is the durable form of the Puia identity question — structural, so no further querying closes it; only Elazar can. Two agents independently reached the same guess from one shared surname, which is evidence about the guess's APPEAL, not about its truth. Both Puia conditionals stay conditional; pmmaster rules on neither until Elazar answers. If confirmed, the convergence is worth having for a specific reason: client-ness travelling with the PERSON while the role does not (client in terra, staff titular in venus) is a STRONGER argument for per-(user,app) metadata than the venus ruling was, because the venus ruling only showed a role is too coarse WITHIN one app. Two independent derivations reaching the same shape from opposite directions — but only after the premise is confirmed. Standing, unchanged: terra leg on hold, coder-terra-cc not to be queued against (live Google-auth failure outranks this), db-enamel-cc authors no shared-users DDL. Nothing time-critical.
  • wi-cli-venus note · 2026-07-30
    OPERATIONAL GUARD on the Puia identity question, at the point where the guess would become data (coder-terra-cc, tag coder-terra-cc-ms7bei8vnc9v): When terra's OPEN item 6 is answered and those client accounts are pre-created, DO NOT populate Puia's email from venus's row on the strength of a shared surname. Under the fleet canonical-email unique index (evolutiva-commons Email Identity), writing an email IS AN IDENTITY ASSERTION — it converts an unverified inference into a stored fact with a DB guarantee behind it, and the guarantee would then hold true about the wrong thing. The address comes from Elazar or from the client, or the account waits. This holds REGARDLESS of how his answer lands: same-human still means terra takes the address from him, not from venus's DB. Also adopting coder-terra-cc's sharpening of the epistemics: 'no join key exists' beats 'I have not checked it', because the latter implies checking was available. It was not. Two records with no shared field are unverifiable IN PRINCIPLE, not merely unverified — and the weaker phrasing invites a later agent to go looking, find nothing, and read the silence as a negative.
  • wi-cli-venus note · 2026-07-30
    RULING CORRECTED BY ITS AUTHOR — supersedes the 'client-ness is a per-user flag, not a role' line recorded earlier on this WI (pmmaster-evolutiva-cc, tag pmmaster-evolutiva-cc-ms7bfffkdcyh). The defect actually demonstrated for venus was NARROWER than the ruling stated: reusing 'titular' — an already-overloaded role — lets a future second titular inherit CR-authoring with nobody performing an act that looks like a grant. That is an argument against REPURPOSING an existing role, not against roles as the mechanism. A DEDICATED 'client' value carries no other capability and so does not reproduce the conflation. BINDING PART, fleet-wide: no repurposed role; the grant must be EXPLICIT and must carry NOTHING ELSE. LOCAL PART, venus (VENUS-317), coder-venus-cc's call: whether venus expresses that as a per-user flag or as a dedicated role value. Both satisfy the binding constraint. Do not quote the earlier over-specified 'flag, not a role' form as fleet shape. Enamel leg (enamel_011, db-enamel-cc): hold RELEASED. The hold only ever barred authoring shared-users DDL on VENUS's answer extrapolated to terra; coder-terra-cc answered from terra's own state instead, so the premise never occurred. Shape is ownerAppKey on groups, mirroring lookupOptions' shared-vs-private split (enamel_003) — terra's need becomes private BY CONSTRUCTION, which dissolves the every-sub-app-inherits blast radius that made this a db-enamel question at all. Still Class-A: audit design-ping before implement, diff review before push, roster-check the auditor at ask time, and confirm 'admin' is not silently reachable from the new value — a dedicated value that ends up admin-adjacent is the rejected 'Director is an admin' grant by a longer route. SCOPE SPLIT worth keeping straight: the Puia identity question does NOT gate the enamel DDL (an appKey-scoped userGroups row is independent of venus's separate DB either way). It gates only this WI's CROSS-APP MODELLING CLAIM. Two different things; only the second waits on Elazar.
  • wi-cli-venus decision · 2026-07-31
    Elazar ruling 2026-07-31, relayed verbatim by coder-venus-cc from CLI (CLI origin, no hub tag exists): 'puia is the same person hence same email. we need a group name for people who can CR and qustions, cliente? i need this built pronto.' RESOLVES the WI's one genuinely open design question (the client principal, Class-A): the principal is a DEDICATED role value 'cliente' in userRoles, carrying CR+questions authoring and nothing else. Never a repurposed titular/docente role, never a native enum, never a second users-shaped table, never a second stored email. Lowercase machine value code, label rendered in Spanish UI. Puia identity: ONE human across venus and terra, SAME EMAIL. The ruling settles the RULE; it contains NO address. Terra's pre-created row takes its value from venus's users row read at write time, authorized by this ruling -- NOT 'Elazar-supplied'. Recording it as Elazar-supplied would make the address unfalsifiable later. The never-derive-from-surname guardrail is satisfied by a read of a stored value on its own merits. Priority: build pronto (Elazar). Legs dispatched 2026-07-31 04:28, independent, none waiting on another: venus VENUS-317 (coder-venus-cc, self-started, design -> audit ping -> migrations, DDL via db-venus-cc); terra TERRA-1 (pm-terra-cc, tag pmmaster-evolutiva-cc-ms8mf91ipomb); enamel appKey-scoped groups shape (pm-enamel-cc, tag pmmaster-evolutiva-cc-ms8mfgqy08h6). Enamel-specific constraint carried into its dispatch: enamel shares a Supabase project with terra and has never written an appEvents row, so every unscoped query is positively reinforced right now and enamel's first write retroactively falsifies them. Any shared-table work carries appKey scoping from the first line, not as a later hardening pass. Open with Elazar, NON-BLOCKING (asked 2026-07-31, tag pmmaster-evolutiva-cc-ms8mfp9dc39m): he wrote 'cliente?' with a question mark. Confirming the name only. Default is 'cliente' and all three legs proceed on it; changing it later costs one migration per app.
  • wi-cli-venus note · 2026-07-31
    SCOPE + HOLD, 2026-07-31 04:31 (pmmaster). ALL THREE LEGS HELD pending an Elazar architecture ruling relayed verbatim from CLI by coder-venus-cc (CLI origin, no hub tag): 'all agents need to be able to use it, lets have one for all projects, or one per project? we did one SOP ticket per project and was not good decicion, have to maintain 3 things that should work the same.' He leans ONE CENTRAL module. Held: terra code leg, enamel ownerAppKey DDL, venus-local shape (coder-venus-cc retracting its stale audit design-ping). Design work continues; nothing merged, no DDL, no push. HOLD COSTS NOTHING - measured by pm-terra-cc: terra has exactly one human who has ever signed in (elazar.pimentel@pensanta.com, admin); Puia's terra row has supabaseAuthId NULL; Pasart has no row. Zero client principals can exercise the surface, so terra can supply no production evidence on central-vs-per-project either; venus and mars can. SPELLING RULED: 'client', NOT 'cliente', in all three apps. Measured 2026-07-30 by db-terra-cc - public.groups already carries admin/alumno/bedel/client/docente/jtp and Puia's terra row already uses it. Elazar's ruling named the concept and he typed the name with a question mark; a second spelling for one concept in a vocabulary enamel also reads would be a shared-vocabulary change requiring db-enamel-cc. Venus adopts (no migration; venus has no such value yet). Put to Elazar with the measurement; default proceeds. THREE OF MY TERRA CONSTRAINTS WITHDRAWN (caught by pm-terra-cc before dispatch): terra has NO users table and NO userRoles - it rides enamel's shared users/groups/userGroups, roles come from vUserGroups scoped to appKey='terra'. Consequence I had backwards: the canonical-email unique index is SHARED between terra and enamel, so ENAMEL holding Puia's address IS a collision. Read before write, enamel-side. ROW CREATION BLOCKED, ruling owed by Elazar: venus holds TWO live Puia rows - sebastian.puia@odontologia.uba.ar (createdVia=access_request_approved) and puia.sebas@gmail.com (createdVia=NULL), both titular, VENUS-142, held dupe #4 of the EVO-73/74/78 merge. 'Same email' names a RULE presuming a single stored string; there are two, so picking one IS the held merge decision arriving by a route that does not look like a merge. db-venus-cc and pm-terra-cc both declined to pick; ratified. Address choice put to Elazar 2026-07-31 (tag pmmaster-evolutiva-cc-ms8mhu4jvnum). NAME COPY BARRED: both venus rows carry nombre='Sebastian'/apellido='Puia' with unclean provenance - the institutional row's accessRequest has both name fields NULL, the gmail accessRequest supplied lowercase 'seba'/'puia' not matching the stored title-cased strings, and 'sebastian.puia' title-cases exactly into 'Sebastian Puia'. Indistinguishable from a derivation of its own local-part. Elazar states nombre/apellido as RECALL, never confirmation. TERRA-1 RE-SCOPED TWICE, final: the '\''client lands on /sin-acceso on every page'\'' gate gap DOES NOT EXIST. coder-terra-cc measured source - homeRouteForRoles already routes client -> /panel (lowest precedence), and /panel admits client via requireAppUserPage([client,admin,bedel]), counts-only, no patient data. The stale line came from terra-commons, quoted rather than read against the tree; pmmaster re-scoped a Class-A leg onto it without checking. TERRA-1 is now the AUTHORING SURFACES only: no CR routes, no clientQuestion routes, no queue views for those categories, no measured write path. Designed thin over shared supportTickets infra so a central pivot costs the homeRouteForRoles target rather than a rebuild. NARROWEST-GRANT SPEC for the central branch (pm-enamel-cc, corrected by pmmaster): no raw DB credentials to venus/mars/pluto agents ever; a SECURITY DEFINER RPC with the caller-vs-owner split (same shape as resolveOrCreatePaciente/bindSupabaseAuthId). CORRECTION, binding: the RPC must DERIVE the caller's appKey from the authenticated identity and NEVER accept it as a parameter - a definer function running with owner privileges lets any caller pass a sibling's key, so caller-supplied scope is a privilege-escalation path that reads as a scoping mechanism and passes every review checking the function exists. Plus three-way revoke (REVOKE ALL FROM PUBLIC, anon, authenticated, then GRANT to the intended caller role) and a must-fail fixture asserting app A with app B's userId is REFUSED. Spec for that branch, not a GO. DURABLE, from three instances tonight: a doc is authoritative about INTENT and never about STATE. terra-commons was not wrong when written - /panel and the client branch landed after it. The check is not 'is this doc trustworthy' but 'does this claim assert current state', and every such claim needs a read regardless of its source's quality.
  • wi-cli-venus blocked · 2026-07-31
    status=blocked
  • wi-cli-venus blocked · 2026-07-31
    Elazar ruling owed on two independent questions, both non-blocking for design work: (1) central-vs-per-project architecture (he leans one central module, relayed from CLI); (2) which of two live Puia addresses is real -- picking one IS the held EVO-73/74/78 merge decision. All three legs held, design continues.
  • wi-cli-venus statusChanged · 2026-07-31
    ELAZAR RULED 2026-07-31, CLI-origin via coder-venus-cc, verbatim (no hub tag exists): '2 yes central. sebastian.puia@odontologia.uba.ar 3 Client ok. 4 grant it, i need venus and terra to use this within the next few hours'. FOUR DECISIONS: 1. ARCHITECTURE = CENTRAL. Store in enamel's DB, appKey-scoped rows, ONE portal UI. Clinical apps carry a link and nothing else. Per-app copies are OFF (his cited precedent: the per-project SOP ticket copy, 'have to maintain 3 things that should work the same'). The terra-shaped argument that carried it (pm-terra-cc): terra's client principals already live in enamel's SHARED users/groups, so a per-project CR module on terra would be a second copy over the SAME identity rows enamel reads. 2. PUIA ADDRESS = sebastian.puia@odontologia.uba.ar (venus row bc9a082a...). 3. SPELLING = client, confirmed by him directly. 4. CREDENTIAL GRANT = approved. DEADLINE: venus + terra usable within hours. BOUNDARY RULED, because the available inference ends in a destructive write: THE ADDRESS PICK AUTHORIZES TERRA'S ROW AND NOTHING ELSE. He chose an address for a terra account; he did NOT rule that venus's puia.sebas@gmail.com row is a duplicate to be merged or soft-deleted. EVO-73/74/78 and VENUS-142 STAY HELD, no lane touches that row. Fourth instance in one night of a ruling read as licensing a step it does not contain. Put to Elazar separately (tag pmmaster-evolutiva-cc-ms8nn4vhu9y0); his call, not ours. LEG SCOPES: - ENAMEL (owner, builds): two tables not one (CR and clientQuestion have opposite authorship direction and different terminal conditions), no enums, lookupOptions status/priority with params.terminal, soft-delete + vActive*, updatedAt BEFORE UPDATE trigger from the first migration, mutation-wrapper + friction telemetry, Spanish UI / English camelCase. Portal route placement decided internally, reported not escalated. - VENUS (coder-venus-cc): Puia client role slice + nav link. No CR/question surface. Venus-local design-ping RETRACTED not amended (a Class-A ask on a dead shape reads as live). Negative-gate review still required: client must not be reachable from any staff-gated surface and must not fall through into an existing branch. - TERRA (pm-terra-cc): row usable + link. No authoring surfaces. homeRouteForRoles already routes client -> /panel; the target may only need repointing. GRANT SPEC, BINDING: no raw DB credentials to venus/mars/pluto lanes. SECURITY DEFINER RPC, caller-vs-owner split (same shape as resolveOrCreatePaciente/bindSupabaseAuthId). THE RPC DERIVES THE CALLER'S appKey FROM THE AUTHENTICATED IDENTITY AND NEVER ACCEPTS IT AS A PARAMETER -- a definer function runs with owner privileges, so a caller-supplied key lets any app write into a sibling's scope, and that passes every review checking the function exists. Three-way revoke (REVOKE ALL FROM PUBLIC, anon, authenticated, then GRANT to the intended caller role only) + a must-fail fixture asserting app A with app B's userId is REFUSED. If what reaches a calling lane accepts an appKey argument, that lane refuses to call it. PRECONDITION IN FLIGHT: db-enamel-cc checking whether enamel already holds sebastian.puia@odontologia.uba.ar. Terra and enamel share users and therefore the canonical-email unique index, so if enamel holds it terra's write is a COLLISION, not a duplicate-person question. Terra does not write until that answer lands. THE CUT (pmmaster, agreed by pm-enamel-cc, stated to Elazar): ships in hours = store + write/read path + minimal portal route + the RPC, with venus and terra linking. Follows later = triage workflow, digests, notification rails, status automation. STILL OPEN WITH ELAZAR, non-blocking: Puia's nombre/apellido as RECALL (both venus rows' name fields are indistinguishable from a title-cased local-part, so no lane copies them); and whether to close the venus gmail row.
  • wi-cli-venus note · 2026-07-31
    TERRA DB LEG CLOSED EMPTY, 2026-07-31 05:04 (db-terra-cc enumeration over a 3-row users table -- enumeration, not a predicate, so 'no duplicate' is a real negative). - ONE Puia row: 6ebaffae-a195-459e-afe8-b89c3fd73fc0, sebastian.puia@odontologia.uba.ar, deletedAt NULL, created 2026-07-30 11:57:37.425521Z. The 'terra-side row from earlier tonight' IS that row -- no duplicate was ever created. - It ALREADY HOLDS terra/client membership: userGroups.fromAt == users.createdAt to the microsecond, so row and grant were one transaction. Nothing to write, nothing to grant. - nombre/apellido populated, so the NOT NULL blocker does not bind for Puia. Name question withdrawn from Elazar (tag pmmaster-evolutiva-cc-ms8nonn4n8ik). - supabaseAuthId NULL -- never signed in; filled by bindSupabaseAuthId on first Google sign-in, enamel's write path. TERRA'S REMAINING LEG: portal link + homeRouteForRoles target, blocked only on enamel's portal URL. Deadline achievable. CORRECTION TO MY OWN RULING (pmmaster, on pm-terra-cc's point): I wrote that the precondition read was the only thing standing between us and manufacturing the duplicate the shared index exists to refuse. FALSE. emailCanonical is GENERATED ALWAYS ... STORED behind a partial unique, so the DB would have REFUSED the INSERT. What the read actually bought was avoiding a failed write and, more importantly, avoiding the WRONG DIAGNOSIS of that failure at 5am under a deadline -- a rejected insert reads as a migration bug long before it reads as 'this person already exists'. I credited the read with preventing a corruption the schema already prevents, borrowing the guarantee's work for the process lesson. Honest form: the structural guard held; the read saved the cycle spent misreading it. STILL TRUE AND SEPARATE (pm-terra-cc's observation, the one worth keeping): the ruling said 'Puia's row usable', every lane including pmmaster read that as a WRITE, and the correct action was a GRANT that already existed. On a shared table, 'create the user' is a claim about what already exists, and nothing in the phrasing announces it. TWO OPEN ITEMS, neither on tonight's deadline, neither terra's: 1. PROVENANCE OF 6ebaffae IS UNRECOVERABLE. Nobody knows who created it or on what authority; it predates db-terra-cc's records and has no provenance record. Elazar's ruling tonight authorized that address for terra FORWARD -- it is not retroactive evidence of who created the row. Correct entry is 'created by an unrecorded hand, provenance unavailable', never a plausible reconstruction. A row with unknown origin holding a live grant into a shared table is load-bearing state under evolutiva-commons 'Unverifiable State Needs An Owner And A Repo-Side Record': named owner + repo-side record + last-verified date + an explicit statement that the origin is not recoverable. Reference shape: terra's own gotrue-config-mirror. 2. INDEX PREDICATE DIVERGES FROM COMMONS. Live predicate is WHERE deletedAt IS NULL AND isSynthetic IS FALSE; fleet commons documents WHERE deletedAt IS NULL. If isSynthetic rows are exempt from the canonical unique, a synthetic row can carry a canonical a real row also carries -- either a deliberate carve-out needing its reason written where a reader of the index finds it, or the gap the index exists to close. Owner: db-enamel-cc. 3. PASART: no row, no address, and the two venus-derived name strings are not available to him either. The name bar and the address bar both still bind. To be filed separately.
  • wi-cli-venus unblocked · 2026-08-19
    Elazar ruled 2026-07-31 (central architecture, Puia address, spelling, grant) - stale blockedReason from before the ruling landed; both legs (TERRA-1, VENUS-317) done, only enamel's ownership/build remains
  • wi-cli-venus statusChanged · 5w ago
    Terra leg filed as TERRA-243 and assigned to coder03-terra-cc, which held zero open items while the other two terra coders carried seven each. GO given on Elazar's behalf under his standing grant. Rationale recorded here because it is the parent's defect, not the child's: EVO-83 sat inProgress 23 days with a PM (me) as its assignee, and a PM does not push code - so the item could never move, and its staleness read as lack of priority rather than lack of a coder. AN ITEM WHOSE ASSIGNEE CANNOT PERFORM ITS DEFINITION OF DONE IS UNOWNED, however filled-in the assignedAgent field looks. Same failure family as an item assigned to an agent that is no longer in the roster, and harder to see, because the assignee is live and answering. EVO-83 stays with me as the fleet-wide parent - the venus leg still has no coder (coder-venus-cc and coder02-venus-cc are both unregistered after Elazar's deliberate shutdown), and the client-principal question there remains genuinely open: venus has no client-facing role distinct from titular. Terra may be able to answer its own version of that question from its existing role model, which is why TERRA-243 is told to answer it from code rather than park it again.
  • wi-cli-venus note · 5w ago
    CORRECTION AND CURRENT STATE, 2026-09-12, pmmaster-evolutiva-cc. READ THIS ITEM'S EVENTS, NOT ITS DESCRIPTION. The description above is the 2026-07-30 filing and is STALE in the one way that matters: it presents the client principal as open and each app as building its own surface. Elazar superseded both on 2026-07-31. ARCHITECTURE IS CENTRAL - enamel's DB, appKey-scoped rows, one portal UI, clinical apps carry a link and nothing else, per-app copies OFF. PRINCIPAL IS SETTLED - a dedicated group value spelled 'client', carrying CR and questions authoring and nothing else. LEG STATUS: TERRA-1 done, VENUS-317 done, ENAMEL LEG IS THE ONLY ONE OUTSTANDING and is now filed as ENAMEL-47, assigned coder02-enamel-cc, which held zero open items. TERRA-243 was filed by me on 2026-09-12 against this stale description and CANCELLED the same hour - it would have built the second copy the central ruling exists to prevent. coder03-terra-cc caught it before any DDL was written, from the ruling in this very event log. Two things worth keeping from that miss. First, this item's own durable note called it in advance: a doc is authoritative about INTENT and never about STATE, and a work item's DESCRIPTION is a doc. The stale-description case is worse than the stale-doc case, because the current state is sitting in the same record one command away, so nothing about the reading felt like skipping a source. Second, the tracker's own shape contributed: 'wi show' prints the description immediately and the last ten events below it, so a long-lived item with a long history presents its oldest framing first and most prominently. For any item where a ruling has superseded the filing, the ruling belongs in the description, not only in an event. ALSO SURVIVING TERRA-243: coder03-terra-cc re-verified terra's client wiring live from source - dedicated 'client' group in public.groups, wired through auth.ts, nav.ts, route-access (client -> /panel, informes aggregate-only, roster and patient data refused) and confirm-actions role checks, with Puia's terra row holding it at userGroups.fromAt == users.createdAt. That is a live confirmation of TERRA-1's done state rather than a restatement of it, and it confirms the 2026-07-31 ruling was implemented as ruled.
  • wi-cli-venus note · 4w ago
    CORRECTION TO THIS ITEM'S OWN DESIGN CONSTRAINTS, verified live against enamel's schema by coder02-enamel-cc on 2026-09-12 before any DDL was written. Both were quoted forward from the 2026-07-30/31 design text into TERRA-243 and ENAMEL-47 by me without being read against the tree. (1) TABLE NAME COLLISION: 'correctionRequests' is an EXISTING, IN-USE table serving terra's rectification workflow. Building this feature under that name would collide with a real and different feature. RATIFIED REPLACEMENT: changeRequests and clientQuestions. Two tables, unchanged - only the names move. (2) THE TERMINALITY MECHANISM NAMED IN THIS ITEM DOES NOT EXIST. This item's constraint reads 'terminality via lookupOptions.params.terminal, exactly as supportTicketStatus does'. lookupOptions HAS NO params COLUMN. The live precedent is a separate matrix table, supportTicketCategoryStatuses. RATIFIED: a scaled-down equivalent of that matrix, not a params lookup. The binding intent is unchanged and is what the constraint was always for - a new status must be an INSERT and not a deploy, and terminality must not be a DB or TS enum. The mechanism named to achieve it was wrong. WHY THIS KEEPS HAPPENING, third instance by me in one night: a doc is authoritative about INTENT and never about STATE, and a design constraint written months ago naming a specific column is a STATE claim wearing an intent claim's clothes. 'No enums, terminality is data' is intent and survives. 'via lookupOptions.params.terminal' is a state claim about a column and needed a read. The failure mode is worse than a stale doc because the constraint reads as settled and authoritative precisely because it is specific - and the more precisely a design rule names a mechanism, the more it needs re-reading against the tree, not less. GENERAL RULE: before quoting a design constraint into a new work item, read every schema object it names. Both of these were resolved FROM CODE by the implementing agent in minutes, which is the outcome the rule should produce; the defect is that I propagated them twice first.
  • wi-cli-venus note · 4w ago
    ENAMEL LEG PUSHED 2026-09-12 - the last outstanding leg of this item, 23 days after it was filed and 43 days after Elazar asked for it. ENAMEL-47 carries the detail: v1 cut complete at 01c0845 / app v0.11.0, with the DB half at b01cb44. All three legs now have shipped code - TERRA-1 (row usable plus link), VENUS-317 (client role slice plus nav link), and now enamel's central store, write path, read path and portal route. NOT CLOSING THIS ITEM. Definition of done is code pushed AND WORKING, and the working half is a live authenticated round-trip through the portal that has not been exercised yet. It is a post-deploy check by ruling rather than a pre-push gate. WHAT THE ROUND-TRIP REQUIRES, recorded because it is the one thing no agent can supply: a real browser session belonging to a user who holds the client group. There is exactly ONE such user live, 6ebaffae-a195-459e-afe8-b89c3fd73fc0, holding client under terra and venus - NOT under enamel - so the exercise is that identity signing in to the central portal and authoring a change request scoped to terra or to venus. No agent has session reach and none should be given a write role to fake it. HISTORY WORTH KEEPING because it changed three decisions tonight: this item's DESCRIPTION still carries its 2026-07-30 framing and four Elazar decisions of 2026-07-31 supersede it. I filed a whole terra build against that stale description and coder03-terra-cc caught it before any DDL. Read the event log, not the description.
  • wi-cli-venus note · 4w ago
    ROUND-TRIP GAP NARROWED 2026-09-12 by db-enamel-cc, and the remaining gap is now precisely scoped rather than 'untested'. It ran the live DB half in a transaction aborted by an ACC99 raise, nothing committed, with the statement SED-EXTRACTED from support-core.ts:241-259 rather than retyped - so it exercised the SHIPPED SQL, not a paraphrase of it. Three arms, user 6ebaffae, whose zero enamel client rows were asserted live in the same run: ARM A verbatim statement with appKey enamel -> 0 rows, REFUSED. ARM B same statement, same user, appKey terra -> 1 row, ACCEPTED. ARM C vUserGroups EXISTS removed, lookupOptions EXISTS intact, appKey enamel -> 1 row, ACCEPTED. Arm B is the discriminator and it is better than what I specified: THE appKey ALONE FLIPS THE VERDICT, proved without touching the code, so the gate is shown to be the thing deciding rather than merely present. Arm C is the forcing in the removal form. Arm B is also the FIRST LIVE EXERCISE OF THAT INSERT PATH EVER - statusValue default 'open' pairs with changeRequest in the matrix, statusMatrix accepts, assignNumber issues a number - so the round-trip can no longer fail on the DB side. Post-rollback: 0 tickets, 0 probe survivors, counters unchanged. COVERAGE, stated by the measurer: proves the shipped SQL gate and both predicates against live triggers. Does NOT exercise TS pre-validation, session-to-actorId, the portal closure, or the node-pg path. CORRECTION TO A BLOCKER I RELAYED: coder02-enamel-cc reported needing a write-capable pg role for the end-to-end arm. That is wrong, and the reason matters - THE APP ITSELF WRITES AS ROLE postgres VIA DATABASE_URL, so the end-to-end arm needs APP-ENV REACH, not a provisioned role. Nobody should be granted a role to close this. WHAT IS ACTUALLY LEFT: one authenticated browser session belonging to 6ebaffae, signing in to the central portal and filing a change request scoped to terra or venus. Everything under it is now proven.
  • support-evolutiva-cc note · 1w ago
    Contenido disponible para esta superficie: bundle consolidado de preguntas abiertas al cliente, 2026-10-06, 22 entradas agrupadas por quien contesta (cliente 17 / Elazar 4 / nadie identificado 1), con consecuencia y filas bloqueadas por cada una. /home/rob/gdrive/projects/evolutiva/shared/client-questions-bundle/2026-10-06-consolidated-client-questions.md — Hallazgo relevante para el diseno de EVO-83: tres documentos de preguntas de Venus redactados en julio no tienen rastro de entrega en ningun canal guardado, y cuatro preguntas que figuran como abiertas ya estaban contestadas en WhatsApp. El problema que EVO-83 resuelve no es redactar las preguntas sino que la entrega y la respuesta queden registradas en el mismo lugar que la pregunta.
feat
2026-07-30 by wi-cli-venus
5w ago