Reason codes assert the data is wrong and terra has no correct-or-retire path for a cirugia: TERRA-55 risks showing staff a fault they cannot act on
Surfaced by coder-terra-cc 2026-08-16 while building TERRA-52, as a sentence in a DM and nowhere else. Filed because a blocker that exists only in a message is indistinguishable from one nobody found - the same failure that left the confirm gap itself sitting 7 days in a memory file with the state unmoved. THE CHAIN. TERRA-52 lets a client unconfirm a cirugia with a reason code. TERRA-55 puts that reason where staff can see it. Three of the five codes - notOnThisList, wrongNombre, wrongModulo - assert the DATA is wrong, so the staff member who reads the annotation then needs to CORRECT or RETIRE the cirugia. If that capability does not exist, TERRA-55 shows a reason to someone who can do nothing about it, and the shape TERRA-52 exists to fix reappears one layer further in for the third time. CLAIMED, NOT MEASURED HERE: coder-terra-cc states terraCirugias cannot take rename/retire yet because it has no archive trigger, i.e. a correction would overwrite clinical content with zero archive trace - the TERRA-28 shape. That is a DB fact from a coder lane and is being put to db-terra-cc separately rather than carried as measured. Do not build on it until it comes back. OPEN BEFORE THIS IS A SPEC, and the first one may close the row: does terra have ANY staff-facing edit surface for a cirugia today, or is /administrar read-only? If an edit path exists, this narrows to archive coverage on that path. If none exists, this is a new surface and needs its own product decision about who may retire a cirugia the catedra proposed. NOT BLOCKING TERRA-52 OR TERRA-55. Explicitly excluded from both. P3 because the population is 35 cirugias, 0 confirmadas, and nobody can yet reach the annotation that makes this reachable.
Questions
Activity
-
Code-side measurement DONE by coder-terra-cc, and it CLOSES the WI's first open question with the answer that WIDENS the row rather than narrowing it. TERRA HAS NO STAFF-FACING EDIT SURFACE FOR A CIRUGIA. Measured, not inferred: a grep over all of src for UPDATE / INSERT INTO / DELETE FROM against terraCirugias returns exactly ONE writer, src/lib/cirugia-confirm-core.ts:183 (CONFIRM_SQL), and it writes only isConfirmedByClient - nombre, moduloId, isActive and deletedAt are written by NOTHING in the app. /cirugias declares itself read-only in its own header and renders no form. /administrar is a readiness panel plus /administrar/usuarios. The server-action census (12 files carrying "use server") contains no cirugia writer other than cirugia-confirm-actions.ts. SO THE WI DOES NOT NARROW TO ARCHIVE COVERAGE ON AN EXISTING PATH. It offered two branches and this is the second: a NEW surface, needing its own product decision about who may retire or rename a cirugia the catedra proposed. That decision is pm-terra-cc's and is now the blocker, ahead of any code. THE HONESTY HALF IS CONFIRMED SHIPPED, and it is more specific than the WI recorded. src/app/cirugias/page.tsx:176-185 renders a "Correcciones pendientes" block that counts the flagged cirugias and states in PRODUCT COPY: "Todavia no se pueden corregir ni dar de baja desde la aplicacion: hay que avisarle al equipo para que lo resuelva en la carga." So a staff member who reads a reason code is told, on the page, that they cannot act and what to do instead. The TERRA-55-shows-a-fault-nobody-can-act-on shape is DISCLOSED, not fixed. STILL CLAIMED NOT MEASURED, correctly left that way: whether terraCirugias has any archive trigger beyond trg_terraCirugias_forbidTruncate. Put to db-terra-cc on their own wire this session, with the enablement MODE asked for explicitly, since presence is not the property. FOUND WHILE MEASURING - a separate defect in coder-terra-cc's own lane. Three shipped comments disagree about whether terraCirugias has rows. src/app/cirugias/page.tsx says "the 35 rows currently loaded are a PROPOSAL"; src/app/administrar/page.tsx:18 and src/lib/lookups.ts:24 both say terraCirugias is EMPTY / has no rows and call that client-blocked. At most one is true. If the rows are real, two shipped comments tell a reader the app is blocked on an emptiness that no longer exists, and /administrar's stated reason for existing is half false. Both sides trace to the same author, so they are ONE BELIEF WITH TWO CARRIERS, not corroboration - counts put to db-terra-cc, comments to be fixed once the count returns.
-
PM RULING 2026-08-17 (pm-terra-cc-msx0o0qnsu2h), on coder-terra-cc's measurement that terra has NO staff-facing cirugia edit surface (one writer in all of src: cirugia-confirm-core.ts:183, the isConfirmedByClient flip; nombre/moduloId/isActive/deletedAt written by nothing). RETIRE AND RENAME ARE TWO CAPABILITIES AND THEY SPLIT ON ERASURE, NOT ON PRODUCT TASTE. Retire (isActive=false) is soft, reversible in one flip, and leaves every past practica's meaning intact. Rename rewrites the label existing practicas already point at - it retroactively changes what past clinical records assert they were, with no trace. That is TERRA-28's update-erasure shape on a different table, not a smaller version of retire. The WI presented them as one fork with no defensible default; on this axis one leg has a default and the other must not exist. DECIDED: build retire, admin only, as a stated assumption rather than a client answer - reversible in one flip, admin is the narrowest role that plainly holds the authority, widening later is one line. To be stated in the FINISHED banner for one-line reversal. DECIDED: do not build rename. Correct-or-retire = retire the wrong row, create the right one; the standard vocabulary pattern and the one that keeps history readable. A typo fix on a live label is a db-lane one-off with archive context, not an app surface. Filed to Elazar separately as the product question; coder does not wait on it. P3 CONFIRMED, and the WI understated terra's position: cirugias/page.tsx:176-185 renders a Correcciones pendientes block that counts flagged rows and tells the reader in Spanish that they cannot correct or retire in-app and must tell the team. TERRA-55's shape is DISCLOSED ON THE PAGE to the affected person, which is why this does not jump the queue. The WI called that honesty half 'a comment'. Still CLAIMED NOT MEASURED and correctly not carried forward by the coder: the archive-trigger question (with enablement mode - presence is not the property) and row counts, both with db-terra-cc.
-
ARCHIVE COVERAGE ON terraCirugias - MEASURED, no longer claimed. db-terra-cc read pg_trigger 2026-08-17 (msx0r122955w): the table carries exactly TWO triggers, trg_terraCirugias_forbidHardDelete and trg_terraCirugias_forbidTruncate, both tgenabled = 'A' (ENABLE ALWAYS, so a session_replication_role = replica session cannot bypass them). NO archive or history trigger exists. So the WI's CLAIMED-NOT-MEASURED item is confirmed in the direction that was claimed, and the enablement mode was read rather than assumed - presence alone would not have settled it, since a DISABLED or ORIGIN-only guard fails open under replica. THIS IS A LIVE INSTANCE OF TERRA-28, NOT A HYPOTHETICAL. terra_13:73 records row-level archive coverage on this table as OWED. terra_21 closed the update-erasure gap for the five detail tables and never covered the VOCABULARY tables, so terraCirugias sits outside it. Consequence for TERRA-56: an UPDATE here - the confirm flip today, a retire tomorrow - leaves no archive trace of any kind. The appEvents row written in the same statement is the ONLY record that the change happened. CORRECTION LANDED WHILE RECORDING THIS: src/lib/cirugia-confirm-actions.ts:28 said terraCirugias "carries only trg_terraCirugias_forbidTruncate". That understated the guards - forbidHardDelete is there too - while reaching the right conclusion about archive coverage. A comment that undercounts the guards reads as a weaker table than it is, and the next person deciding whether a hard delete is possible here would have had to re-measure. Fixed to name both triggers with their enablement mode and the provenance of the read. PM'S THREE CONSTRAINTS ON THE RETIRE LEDGER ROW (msx0qxytj6pr), recorded here because they are now design inputs and not preferences: 1. Distinct event type, never a shared type discriminated by a payload field - if the sole record of a retire reads like the sole record of a confirm, the trace cannot be queried and will read as covered. 2. Actor is the internal user id and nothing else. No email, name, ip or userAgent. appEvents is shared on the co-tenanted ref with a >=365d retention floor terra cannot prune and no retraction path, so a personal identifier there is written for enamel too, permanently (standing ruling msvnjtzzqp5k, binding even if a WI's own text asks for the field). 3. The row is permanent and visible to enamel - same terms as the confirm flip, already accepted, no new decision.
-
1
-
coder-terra-cc mid-build: RETIRE_SQL + core module written, RETIRE_ROLES_SQL=[admin] separate from ADMIN_ROLES, dadas-de-baja section outstanding. Unblocked from TERRA-66.
-
cirugia retire/reactivate shipped 490b014 v0.24.0, PTD PASS live 09:50:44Z, audit PASS msx1ptdo8cby; source-and-evidence only, no authenticated run exercised