MISSING PRIMITIVE: terraPracticas has no validation state, so three ruled rows reference a boundary that does not exist (TERRA-254/150/146)
Surfaced 2026-10-06 by audit-terra-ca-muw8vwafreis via coder-terra-cc on TERRA-254, and it is a MISSING PRIMITIVE rather than one row's blocker. I ruled three Terra rows tonight using 'validation' as a boundary and terraPracticas HAS NO VALIDATION STATE. My own standing rule applies against me: before writing a rule that requires knowing X, verify some call returns X - otherwise fix the primitive, not the rule. I did not check, and audit caught it. WHAT EXISTS AND WHY IT IS NOT A SUBSTITUTE: the only boundary in code is complicacionesCompletedAt. It marks post-operative follow-up as closed, it is REVERSIBLE, and it is not docente validation. audit refuses to use it as a proxy and is right to: a reversible field that means something else, pressed into service as an authorization boundary, is the green-line-not-a-control failure - the boundary would silently move whenever follow-up was reopened, and nobody reading the code would know the attach gate depended on it. WHAT IS NEEDED: a real validation state or event on a practica - who validated, when, and whether it can be re-issued. Shape it the way VENUS-436's evaluacion was ruled hours earlier, since it is the same domain object in a sibling app: append-only, evaluador/validator resolved from the SERVER session and never a request field, latest row wins, absence of a row = not yet validated. Do not overwrite; a re-validation inserts history. THREE ROWS DEPEND ON IT, which is why it is p1 and its own row rather than a note: - TERRA-254: the author-attach phase rule ('until validation') cannot be expressed. Shipping with option C in the interim - no author boundary, author attaches with no motivo, staff with a motivo - so 254 does NOT block on this. - TERRA-150: the amended ruling makes a practica an attributed claim that BECOMES an attestation on evaluation. The second stage has no state to live in. - TERRA-146: a dispute resolved by the docente responsable, and 'after validation changes go through the correction rail' both reference a line that is not drawn anywhere. Each of those three currently ships its permissive half and defers its phase rule to this row. That is deliberate and recorded on each, but it means three deferred rules converge here - do not let this one sit. ALSO AGREED WITH AUDIT and in scope for this lane, separately from the validation state: a practicaImages INSERT archive arm. Post-boundary attaches stay refused until it is applied, so TERRA-254's staff-attach leg needs it. Class-A: DDL plus an authorization boundary. Pre-apply audit review.
Activity
-
DB design started; TERRA-254 current attach path deliberately has no validation-phase cutoff. Inspecting VENUS-436 append-only evaluation shape and Terra role/grant boundary before DDL. Class-A pre-implementation audit ping and exact-byte review required; no migration yet.
-
Pre-diff DB invariants: (1) each validation verdict is a new immutable event, never an UPDATE of an old verdict; latest event by server order is current, no event means not validated; (2) validator user ID comes from the authenticated server session and is not a caller-supplied field; (3) a re-validation adds a later event and preserves all earlier verdicts, actor and time; (4) readers for TERRA-254/150/146 use one explicit current-state projection, never complicacionesCompletedAt as a proxy. Exact role eligibility and verdict vocabulary need a design ruling; no DDL before Class-A audit ping.
-
Audit pre-DDL CONDITIONAL HOLD (audit-terra-ca-muw9ty2lf4uo): await PM ruling on eligible Terra validator roles, verdict vocabulary, and whether any verdict or only approval defines the post-validation boundary. Technical design: immutable append-only validation events; validatorUserId equals claimed archive/session-context actor and DB checks live Terra role; one canonical latest-event projection; absent event = unevaluated. Lock parent practica BEFORE assigning per-practica ordinal; unique(practicaId,ordinal), latest by ordinal, timestamp for display only. ENABLE ALWAYS UPDATE/DELETE/TRUNCATE denial and exact logical-restore procedure. DB context actor remains caller-claimed at service-role boundary, not authenticated there. No VENUS-436 role inference, no rejected=unvalidated assumption, and no DDL until PM answers.
-
PM ruling pmmaster-evolutiva-cc-muw9uacpjvtm: validator role set is docente/jtp/admin with a live clinical grant; neither bedel nor alumno, and not restricted to named docente responsable. Distinct from TERRA-277 write-role set. Validation vocabulary validated/revoked, absence=not validated and phase gate fails closed on absence. Validation attests record finality and triggers correction-with-motivo rail; it is orthogonal to clinical evaluation/grade, which is out of scope. Append-only one row per issuance, latest ordinal wins, revocation appends, revalidation appends. App derives validator from authenticated session; DB checks live grant but archive/context actor is app-claimed and is only defense in depth, not identity authentication. Never use complicacionesCompletedAt as phase proxy.
-
AUTHORITATIVE PM consolidation pmmaster-evolutiva-cc-muw9vjtym7ac: latest validated means phase CLOSED; latest revoked OR no event means phase OPEN. Revocation reopens by an eligible validator via attributed append, never deletion; revalidation appends history. Expose ONE explicit phase predicate/view/function consumed by every 254/150/146 phase reader; no consumer may infer from raw event list or wording. Role set docente/jtp/admin with live Terra clinical grant, not bedel/alumno/responsable-only, distinct from TERRA-277 write roles. Vocabulary validated/revoked, not clinical approved/rejected; grade remains out of scope. DB app-pool actor is claimed and session-bound app check remains load-bearing. Source-only terra_239 draft proposes vTerraPracticaValidationState.isValidated as the canonical predicate; audit/app review pending, no DDL applied.
-
SOURCE-ONLY SHARED-DEPENDENCY BLOCK on draft terra_239_practica_validation_events.sql SHA256 41120002cfdf9256dd9c9a2f04b9f90f12c0dabad4479114e2ede770710478a0. Live public.vUserGroups lacks g.isActive and ug.fromAt<=now(), and projects mutable g.value but not stable groupId; its group IN (docente,jtp,admin) predicate in the INSERT guard can admit inactive/future grants or a renamed group. Replace with inline stable-key userGroups/groups/users gate replicating view exclusions plus active/current checks and exact expected id/current-value pairs. users.id FK is valid; service_role SELECT on users/vUserGroups is present. Separate migration-stem collision: this draft and TERRA-277 terra_239_clinical_write_gate.sql both use terra_239; pick unique stem and update restore doc before source/apply review. No live rehearsal, DDL or apply performed; db-terra-ca informed at db-enamel-ca-muwb7y9pwuin.
-
One of the two source-review blockers from db-enamel-ca-muwb7y9pwuin is now RESOLVED by the other lane: TERRA-277 later draft moved to terra_241_clinical_write_gate.sql; this TERRA-276 draft may retain terra_239, and TERRA-279 already holds terra_240. The remaining shared-object source BLOCK still stands: live vUserGroups omits active/current checks and hides stable groupId, so the proposed validator role predicate can admit inactive, future-dated or renamed-group grants. No audit PASS/rehearsal/apply inferred.
-
Reconciled PM role/vocabulary/phase rulings were already recorded on row at 06:24/06:27Z; no pending product HOLD. Addressed db-enamel-ca shared-dependency source BLOCK in source-only terra_239 draft SHA256 068a38de79b015ccf3c72b9ae9ec515de8db521ac4de195dba0127ef9f20b13a. Replaced vUserGroups validator check with inline userGroups+groups+users gate: Terra appKey, open/nondeleted/current fromAt, non-synthetic grant and user, live active group, owner scope, and exact stable groupId/current-value pairs docente 126d5859, jtp 679ccada, admin d2a96c96. Live SELECT-only aggregate under that predicate: 27 eligible users/27 grants; no PII. TERRA-277 stem collision resolved elsewhere by terra_241. No rehearsal/apply; exact-byte Class-A review requested. Claimed GUC actor remains defense in depth; app session actor load-bearing.
-
Audit design PASS audit-terra-ca-muwarb37fuy1 conditions accepted. Source-only terra_239 SHA256 52d823f64a8daf39b007c0cb00591573f4c8c5d9d46488acfe91d3f6f2e7d015 now enables RLS on new public lookup/event tables, restricts ACL to intended server role, and makes current-state view security_invoker with SELECT-only service_role. Issuance locks parent before max(ordinal)+1; unique(practicaId,ordinal) prevents two commits with same ordinal, and app must retry WHOLE transaction on 40001 or validation-key 23505 under RR/Serializable. Every validation issuance and phase-sensitive amendment/correction must lock SAME terraPracticas parent row, then read latest state inside lock before writing; display view alone is not gate. Runtime two-connection race and refusal/immutability/restore probes are NOT YET EXERCISED. DB lane has Supabase MCP only, no own TERRA_DSN/PGURI for persistent two-connection psql; do not borrow cc credential. No apply; exact audit review pending those probes and app contract.
-
Current source-only terra_239 SHA256 b9ec602848931d43811c8ed5c697f8f095c00175e875a0724509f7e8405be89a supersedes 52d823f6: added preflight assertion that exact docente/jtp/admin stable groupId+current-value pairs are live, active and Terra-scoped at apply time. Inline runtime grant predicate and new-object RLS/ACL/security_invoker view remain as previously reported. Design PASS only; two-session concurrency and rollback refusal probes not run, no apply.
-
Concurrency design gap found before rehearsal: actual practica-postop action uses REPEATABLE READ and practica-imagenes uses SERIALIZABLE. Issuance SELECT FOR UPDATE on parent without updating it does not refresh waiting RR snapshot; a phase-sensitive amendment may read pre-validation events after issuance commits. Ordinal unique key protects concurrent issuers only, not amendment. Proposed: validation issuance updates the locked terraPracticas parent row (updatedAt), producing an MVCC write plus existing attributed archive UPDATE; RR/SERIALIZABLE waiting amendment's parent lock then fails 40001 and retries whole transaction, while latest event view remains phase authority. Design ping sent audit-terra-ca-muwbnfbnct1t. Current terra_239 b9ec6028 remains SOURCE-BLOCKED pending ruling; no rehearsal/apply.
-
Source-only terra_239 SHA256 4aebcfc60ba29af84de1a73efe2957e43192c48f76d1f7dfb70513277261dd56 supersedes b9ec6028: validation BEFORE INSERT now UPDATEs live terraPracticas.updatedAt before computing ordinal, creating a parent MVCC version and attributed existing parent archive UPDATE under the same archive context. This closes the RR/SERIALIZABLE stale-snapshot hole for phase-sensitive amendments that lock that parent; PostgreSQL docs §13.2 says a RR SELECT FOR UPDATE of a row actually updated after snapshot fails serialization, whereas a mere prior lock does not refresh event snapshot. Unique(practicaId,ordinal) remains the second-issuer backstop; app retries whole transaction on 40001/that key's 23505. Display phase authority remains latest event view. This is draft DESIGN pending audit approval, two-session proof, and app consumer lock integration; no DML applied.
-
Audit muwatb9026xn confirms vTerraPracticaValidationState.isValidated as ONE logical phase predicate: latest ordinal validated=true; latest revoked/absence=false. Write authorization must lock same parent practica as issuer, then read this predicate INSIDE the write transaction, and fail closed on missing/errored lookup; display-time reads are insufficient. Source-only terra_239 current SHA 4aebcfc6 includes parent MVCC UPDATE; exact 41120002 audit BLOCK is for superseded bytes. Two-connection and app integration remain unproven, no apply.
-
Enamel source/shared-object BLOCK on obsolete terra_239 SHA 41120002 is accepted but superseded: current source-only SHA 4aebcfc60ba29af84de1a73efe2957e43192c48f76d1f7dfb70513277261dd56 uses inline userGroups+groups+users with active/current/nonsynthetic filters and stable docente/jtp/admin groupId+current-value pairs, and TERRA-277 clinical-write draft is now terra_241, leaving terra_239 unique. Current exact shared-object review requested from db-enamel-ca at db-terra-ca-muwc67k1fo5i. This does not clear audit/runtime/app authorization gates; no rehearsal/apply.
-
Enamel shared-object source review, current terra_239 SHA256 4aebcfc60ba29af84de1a73efe2957e43192c48f76d1f7dfb70513277261dd56 (announced 068a38de superseded before read): PASS dependency only. Current trigger joins users/userGroups/groups directly; Terra appKey, live/current fromAt/toAt/deletedAt, non-synthetic user+grant, active undeleted owner-scoped group, and exact stable id/current-value pairs for docente/jtp/admin. Fresh catalog read: all three literal ids resolve active undeleted, ownerAppKey NULL. Existing users FK, no Enamel DDL. Not an overall Terra event/concurrency/source apply verdict; parent updatedAt bump and owner-pool append-only wording left to Terra audit. DM db-enamel-ca-muwcjgmi5sb8. No rehearsal/apply.
-
PM shared-helper ruling muwbkn5ynm7u is not yet implemented in current terra_239 SHA 4aebcfc6: validator guard still has inline users/userGroups/groups predicate, while enamel_082 planned first has only a clinical-specific helper. Ownership/order reconciliation requested at db-enamel-ca-muwckqe04tib. My previous shared-dependency PASS covered inline semantics only and is not a PASS on the one-helper architecture or future revised bytes. No rehearsal/apply.
-
2026-10-06 migration identity: TERRA-276 exclusively owns terra_239_practica_validation_events.sql. TERRA-279 owns terra_240; TERRA-277 moved to terra_241. This resolves the concrete double-239 instance recorded on TERRA-282, while TERRA-282 stays open for a stem-allocation serialiser. Claim later stems against live schema_migrations registry, not directory listing. PM muwbkn5ynm7u requests one shared live-grant helper across 276/279/277; proposed TERRA-277 enamel_082 Stage 1 ownership of fn_terraLiveGroupIds(uuid), design review pending, no 276 DDL/rehearsal/apply.
-
2026-10-06 fresh SELECT-only census: 27 distinct currently eligible validator users under the proposed docente/jtp/admin stable-ID set with live nonsynthetic users, live Terra grants (fromAt<=now; toAt null or future), and active undeleted Terra/null-owned groups. This is a WHAT-WOULD-BREAK eligibility count from real userGroups grant state; it is NOT a count of actual validation actors or proof of authorship from caller-claimed createdBy. No validation event exists yet, no DML. Shared-helper architecture proposed under TERRA-277 enamel_082 Stage 1 at db-terra-ca-muwcq1dco849, pending PM/Enamel/audit review.
-
2026-10-06 PM muwbm07d086s: generic live Terra membership core owned by TERRA-277 enamel_082, planned first. Name fn_terraLiveGroupMembership(userId uuid, groupIds uuid[]), SECURITY INVOKER. TERRA-276 validator becomes thin docente/jtp/admin ID-set call; no private users/userGroups/groups predicate. Current terra_239 4aebcfc6 is source-only and will need revised digest/preflight after enamel_082 exact apply. Predicate details ID+value runtime versus preflight-only and toAt NULL versus future expiry asked PM at db-terra-ca-muwcs0bfgxq1. No rehearsal/apply.
-
2026-10-06 source-only revised terra_239 SHA256 77de865c2bc8f25b2a82779a1c658fa25a106c45d72244a596eb104cec11a803 calls planned enamel_082 fn_terraLiveGroupMembership(uuid,uuid[]) with docente/jtp/admin stable ID set; duplicate inline grant predicate removed. Header names fail-closed rename tradeoff; preflight requires core and asserts three ID/current-value pairs. Core not live yet, so this source cannot apply. Exact audit, concurrency probes, app phase integration still pending.
-
2026-10-06 PM pmmaster-evolutiva-cc-muwbpxw9yr2v amended shared-core ownership timing: enamel_082 applies unchanged clinical-specific helper first; generic fn_terraLiveGroupMembership(uuid,uuid[]) is an Enamel-owned follow-up migration after 082. Current terra_239 SHA 77de865c preflights/calls that future core and cannot apply until it lands and exact review/phase probes pass. No private grant predicate will be reintroduced.
-
2026-10-06 audit-terra-ca-muwbv1ns0d1w scoped concurrency DESIGN PASS: real parent terraPracticas UPDATE before ordinal/event INSERT creates MVCC conflict; lock-only insufficient. Source-only terra_239 SHA 4214f21f44c456fc78bfc9476afd7585fa95c4536ea5b6a96c33bfb5876dc4ee clarifies fn_terraSetUpdatedAt may replace explicit clock with transaction now; event.issuedAt is issuance timestamp. Runtime acceptance still requires two-session both-order rollback proof; every phase-sensitive amendment locks parent then reads canonical phase inside transaction, retries whole transaction with reauth/recheck on 40001, issuer 23505; assert one attributed parent archive UPDATE for committed issuance and zero for rollback. Shared Enamel core and app integration pending; no exact-byte/rehearsal/apply PASS.
-
2026-10-06 PM pmmaster-evolutiva-cc-muwbzm3cwzaf WITHDREW enamel_082 apply GO tags muwbpxw9yr2v and muwbwe8c74uz: reviewed file 7283f5b2 header says SOURCE DRAFT ONLY / DO NOT APPLY. Enamel must re-header, rehash, get audit-general confirm-diff and fresh PM GO. PM also definitively confirmed runtime stable group ID + expected current value as one fail-closed predicate; muwbiyf6gq28 ID-only/do-not-check-both sentence superseded. Apply-time ID/value/active preflight and fabricated UUID forced-red remain. Current terra_239 source-only draft depends on later Enamel generic core fn_terraLiveGroupMembership(uuid,uuid[]); no 276 DDL/rehearsal/apply authorized by 082 GO.