Estado: NOTA DE INVESTIGACIÓN (posterior a la auditoría, previa al plan). Sin código. Según docs/PROCESS.md §1.1, el análisis exploratorio vive en docs/research/ hasta que se compromete a un sprint. Fecha: 2026-07-24 Método: dos rondas de flujo de trabajo — ronda 1 = 10 afirmaciones × (1 verificador + 2 escépticos adversarios) + síntesis + crítico de exhaustividad (32 agentes); ronda 2 = 12 sondas dirigidas que cierran los hallazgos del crítico + una pasada de corrección (13 agentes). Asunto: las afirmaciones sobre huecos del marco en `repair-shop-dept-model.md` §11 («lo que el marco tiene que originar») y sus afirmaciones de hueco verificado incrustadas.
---
Por qué existe esta nota
repair-shop-dept-model.md se guardó el mismo día en que se escribió. Su §11 afirma seis cosas que le faltan al marco, más varias afirmaciones de «X existe disfrazado». Esas afirmaciones están en la ruta crítica de la planeación de cosecha: si una está equivocada en el sentido de ausente, reconstruimos código ya publicado (la clase de falla del Gate 0.6), y si una está equivocada en el sentido de existe, nos saltamos un hueco real. Esta nota registra qué sobrevivió a la verificación.
Titular: las afirmaciones positivas aguantaron; las de ausencia, en su mayoría, no. Un agente que abre un archivo y encuentra algo produce evidencia fuerte. Un agente que busca y no encuentra nada produce evidencia débil, y la ronda 1 presentó las dos con la misma confianza. Esa sola confusión es la que la ronda 2 tuvo que deshacer.
---
Dos errores de método que vale la pena llevarse
1. Los directorios clonados inflan toda cuenta de consumidores entre repositorios. Ocho directorios hermanos bajo ~/projects — rp-0.98-wt, rp-agent-wt, rp-b007-wt, rp-dlpmt-wt, rp-frozen-95acda76, rp-repo-inventory-wt, wt-harvest-frigate-box y poppersanddildos/rust-primitives/ — son clones de rust-framework-workspace, no consumidores. wt-harvest-frigate-box en particular trae envoltorios application-travel-compliance / application-runbook que se leen como adopción externa y no lo son. Cualquier cifra de «N consumidores» que no los quite está mal.
2. La justificación de un aplazamiento, en este repositorio, vive en los README de las piezas y en los `COMMENT ON COLUMN` del SQL, no en `docs/`. Una búsqueda acotada a docs/ para responder «¿esta barrera es deliberada o quedó abandonada?» es estructuralmente incapaz de responder la pregunta aquí. La ronda 1 dejó cuatro barreras como UNVERIFIED exactamente por eso; la ronda 2 resolvió tres leyendo los README.
Corolario: un documento del mismo día no puede servir de justificación previa para nada. La ronda 1 empezó citando repair-shop-dept-model.md a sí mismo como evidencia de apoyo.
---
Correcciones que se le deben a repair-shop-dept-model.md
Son errores de hecho que hoy circulan en una nota ya guardada. Se listan con la evidencia que los tumba. La nota no se ha editado — es una foto fechada de la reconstrucción de una sesión, y reescribirla destruiría esa procedencia. Esta sección es la corrección de registro; léanse las dos juntas.
| Afirmación de la nota | Corrección |
|---|---|
| §11.2 — «"autorizo destruir este disco" no se puede representar, y un cliente de mostrador no tiene sesión con la que consentir» | Falso. operations-approval-workflow trae ApprovalProposal{entity_type, entity_id, workflow_kind, payload, proposer_party_id, reviewer_party_id, …} — acotado al objeto y con clave de parte, así que no hace falta ninguna sesión. Está conectado (POST /approvals/:id/approve), con permisos (/staff/approvals) y presente en el esquema de la aplicación publicada (application-engine/migrations/050:35). Hueco residual: reviewer_party_id no tiene llave foránea, así que es una declaración afirmada por el personal, no una firma del cliente. |
| §11.6 — «Nada modela "estos N objetos pertenecen a un mismo trabajo" … ni storage-locations ni inventory tienen el kit» | Falso dos veces. catalog::ItemType::{Kit,Set,Lot,Pair} + BundleItem + bundle_items vienen con CRUD de administración ya conectado; y production_items + block_finalized_production_edit (application-legal-evidence/migrations/0001:213-226) es una barrera de «no se añade ni se quita una vez sellado» impuesta por la base de datos. La mitad del reclamo sobre stock_placements sí es correcta — su UNIQUE es (item_id, location_id). |
| §5.2 — «los dos generadores aleatorios de 6 caracteres … están copiados y pegados» | Falso. Algoritmos y espacios de claves distintos: reservaciones toma los primeros 6 bytes del UUID → base36 (36⁶); agenda calcula (millis ^ uuid) % 1_000_000 → decimal (10⁶). Reinvenciones independientes: no hay un solo envoltorio que arreglar. |
| §5.2 — «COLISIÓN SIN COMPROBAR» | Exagerado. Las dos tablas llevan restricciones UNIQUE reales. El defecto es la ausencia de reintento: una colisión sale como un 23505 sin manejar. Registrado como B-014. |
| §9 — el runbook no tiene registro de ejecución (dando a entender que el marco tampoco) | Literalmente cierto, la implicación falsa: domain-curriculum es un motor persistido de plantilla → versión → paso ordenado → corrida → terminación por paso → evento sellado con actor. Salvedad: no tiene ningún consumidor en ninguna parte, y el consumidor previsto que nombra (baloo) no es un proyecto en Rust. |
| §11.3 — «`workflow_transition_history.at` lo aporta correctamente PERO SOLO para entidades que usan el almacén CAS» | Dos errores. (a) encounters aporta una marca de tiempo de entrada igual de confiable mediante un disparador AFTER UPDATE sin ninguna exigencia de CAS (encounters/migrations/001:118-133). (b) El libro mayor sí se escribe en producción — migración 00028 de ~/projects/support + ticket/service.rs:295 pasa un actor real. |
| §11.1 — «`storage_locations.default_workflow` … no tiene usuarios» | Engañoso. Tiene usuarios de CRUD y de API, sobre una copia vendida de la columna en otra tabla (application-catalog), y un consumidor de comportamiento en otro repositorio (~/projects/rust-inventory-ai/src/repo/locations.rs:17). La redacción exacta es: «un paso de solo escritura — nada lee el identificador para despachar un flujo de trabajo.» Su COMMENT ON COLUMN la registra como un desacoplamiento deliberado de Gate 1.5; no la borren. |
§11 cierre — legal-evidence / travel-compliance / legal-matter::LegalHold son kits generales «disfrazados» | Los tres equivocados tal como están escritos. legal-evidence no tiene tipo de custodia (el libro mayor está en el plano de la base, dentro del módulo forge). travel-compliance está acoplado a animal/especie/país y no tiene migraciones. LegalHold solo es «sin vencimiento» — está indexado por un solo matter_id, no tiene ningún lector, y su ON DELETE CASCADE es lo inverso de un gravamen. El sustrato genuinamente libre de dominio es application-core::sql_invariants. |
---
Qué cambió la ronda 2 sobre los huecos propuestos
| Hueco | Ronda 1 | Ronda 2 |
|---|---|---|
| Nodo de departamento (enlace de seis facetas) | COSECHA NUEVA, grande; «facetas dispersas en cinco piezas» | ABARATADO a cableado. Las facetas están juntas en un solo tipo, en un solo archivo — Guard :107, Action :132, with_roles :367, requires_approval :380, StateType::{Blocking,Waiting} :164-165, available_transitions_for_role :505. El filtrado por rol ya está vivo y probado. |
entered_state_at + presupuesto de permanencia | Bloqueado — «la base de la aplicación desplegada no tiene fuente de entrada de estado» | BLOQUEO RETIRADO. La captura está publicada y corre en vivo en ~/projects/support. El trabajo está del lado de la lectura (no hay API de consulta) más generalizar el presupuesto sacándolo del literal 'processing' que decisioning tiene escrito a mano. |
| Registro de destrucción declarada | COSECHA NUEVA | ABARATADO. WipeMethod{QuickWipe,DdZeros,Shred,SecureErase} existe, con un consumidor en producción en rust-inventory-ai. Solo falta conectarlo dentro de DeletionRequest::complete(). |
| Asignador de identificadores | AUSENTE | La conclusión aguanta, el razonamiento se reescribe. La ronda 1 nunca abrió identity-identifiers ni application-identifiers — piezas nombradas justo por el hueco. Resulta que son solo almacenamiento (guardan valores que les da quien las llama). Existen dos bases exactas de donde levantarlo dentro de la flota. Registrado como B-014. |
| Kit de custodia de varios objetos | HÍBRIDO | ACOTADO. foundation-decisioning y operations-workitem quedaron los dos DESCARTADOS como casas candidatas. |
| Barrera de depósito | HÍBRIDO | Sin cambio — nunca se volvió a sondear. UNVERIFIED. |
---
Registrado a partir de esta auditoría
- B-012 — el veredicto de SLA se invierte al reabrir;
pause_on_waitingno tiene
ningún sitio de lectura (P1)
- B-013 —
waiting_on_clientes una trampa de una sola salida; el SLA corre
durante el silencio del cliente (P2)
- B-014 — la colisión de código de confirmación sale como un 500; la prueba de
unicidad no afirma nada (P2)
- B-015 — las barreras y acciones de
operations-workflowson solo declarativas,
ningún anfitrión las interpreta (P2)
- DEUDA TÉCNICA —
TD-FMT-WORKSPACE-RED,TD-DECLARED-SHADOWED-DEPS,
TD-ARCH-MD-NO-STATUS, TD-INVARIANTS-MD-MISSING, TD-TAB-DISCIPLINE-DOC-CONFLICT
- PENDIENTES DE COSECHA — renglones candidatos 14–23 (lista de pistas;
comprobar antes de ejecutar)
Cada B-NNN de arriba se volvió a verificar de forma independiente leyendo el archivo directamente antes de registrarlo, no se transcribió del reporte de un agente. Los renglones de pendientes no: llevan la salvedad del preámbulo existente, «lista de pistas, no verdad de campo».
Todavía sin verificar — y no se está tapando
1. La barrera de depósito (¿se consulta la propiedad antes de decidir un desecho?) — ninguna sonda la tocó. 2. Si el sellado de `production_items` se generaliza a un manifiesto físico de custodia de varios objetos — nadie abrió el código de catálogo y producción para comprobarlo. 3. Si el presupuesto de reclamo por antigüedad de `decisioning` se puede generalizar sin romper sus tres consumidores vivos de IdempotencyStore — una pregunta del lado productor del Gate 4.5. 4. Si vale la pena arreglar los huecos de `application-tickets` — no tiene ningún anfitrión dentro del árbol mientras dos consumidores externos montan su enrutador. Llevarlo a paridad frente a darlo de baja en favor de la ruta de encounters está sin decidir, y cambia materialmente el alcance de B-013. 5. El radio de impacto de `ARCHITECTURE.md` — la clase de defecto está probada para una pieza; cuántos de los 231 documentos generados por pieza lo comparten nunca se contó.