Auditamos 10 repositorios Rust que abarcan inferencia AI, agent runtimes, autenticacion, busqueda, servicios de gobierno, aprendizaje etico y emulacion — 365 archivos fuente con 1,025+ tests. Cada .unwrap() y .expect() en produccion fue clasificado manualmente: 140 en total, todos invariantes algoritmicos o patron CLI-startup. Se encontraron y corrigieron 8 problemas accionables: 5 riesgos de panic por NaN via partial_cmp().unwrap(), 1 crash en verificacion de hash-chain, 1 propagacion de error no controlada, y 1 unwrap ambiguo mejorado a expect explicito. Se construyo un scanner de analisis estatico propio que fue mejorado durante la auditoria, encontrando 4 bugs en nuestra propia herramienta. Resultado final: 0 riesgos P0, 0 unwraps accionables restantes.
Cada hallazgo fue detectado, clasificado, corregido y verificado con tests durante la auditoria.
partial_cmp().unwrap() en valores f32 genera panic cuando un operando es NaN. Encontrado en sampling de tokens LLM (argmax, top-k sort, top-p sort) y scoring de confianza en deteccion de anomalias.llm-sampler/src/lib.rs — lineas 192, 204, 225llm-models/src/llama.rs — linea 880b3-core/detectors.rs — linea 330
// Antes (panic con NaN): .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap()) // Despues (NaN-safe, orden total): .max_by(|(_, a), (_, b)| a.total_cmp(b))
partial_cmp().unwrap() → total_cmp(). 88 + 88 tests pasan.
verify() de un log append-only de hash-chain usaba serde_json::from_str(&line).unwrap(). Una linea malformada (corrupcion de disco, escritura parcial) causaria panic en lugar de retornar fallo de verificacion.logstore/src/lib.rs — linea 158, funcion verify()// Antes (panic con JSON malformado): let v: serde_json::Value = serde_json::from_str(&line).unwrap(); // Despues (retorna chain-invalid sin crash): let v: serde_json::Value = match serde_json::from_str(&line) { Ok(v) => v, Err(_) => return Ok(false), };
Ok(false) en fallo de parseo. 41 tests pasan.
submit(request).unwrap() en una ruta de ejecucion tragaba el tipo de error. Si el canal de intervencion estaba cerrado, el runtime crasheaba en lugar de propagar el error.runtime.rs — linea 243// Antes: submit(request).unwrap(); // Despues: submit(request)?; // + Intervention(#[from] InterventionError) en RuntimeError
.unwrap() → ? con nueva variante InterventionError. 179 tests pasan.
llm-quant/src/*.rs (5), llm-core/src/tensor.rs (3), carga GGUF (2)// Antes (cast crudo, sin validacion): let ptr = bytes.as_ptr() as *const f16; let slice = unsafe { std::slice::from_raw_parts(ptr, count) }; // Despues (seguro, validado por bytemuck): let slice: &[f16] = bytemuck::try_cast_slice(bytes) .map_err(|e| TensorError::AlignmentError(e))?;
bytemuck. 9 unsafe restantes son Metal FFI, Send/Sync, mmap — documentados con comentarios SAFETY. 7 tests de limites agregados.
Construimos un scanner de analisis estatico propio durante la auditoria. Encontro 4 bugs en si mismo.
#[cfg(test)] mod tests; → src/tests.rs no era seguido. +27 falsos positivos. Fix: collect_test_module_paths().\bunsafe\b matcheaba dentro de string literals y comentarios. Fix: count_real_unsafe() con stripping previo.Parser::expect(TokenKind, msg)? matcheaba el regex .expect(. +16 falsos positivos. Fix: requerir argumento string literal./// y //! con .unwrap() contaban como codigo prod. +18 falsos positivos. Fix: strip_doc_comments().panic!, todo! o unimplemented! en codigo de produccion en los 10 repos.partial_cmp en floats es un punto ciego sistemico. Encontrado en 3 de 10 repos independientemente. total_cmp deberia ser el default para todo ordenamiento f32 en Rust..expect("msg") en fn main — patron CLI correcto. Pero 1 unwrap en verify() de libreria era un riesgo real..unwrap(), .expect(), panic!, unsafe por archivo, excluyendo codigo de test.Cada repo evaluado por: conteo de unwraps prod, cobertura de tests, uso de unsafe, calidad de documentacion de invariantes.
Patrones recurrentes en el ecosistema de 10 repos.
| Patron | Repos | Cantidad | Estado |
|---|---|---|---|
partial_cmp().unwrap() en f32 | 3 / 10 | 5 | CORREGIDO |
CLI .expect("msg") en fn main | 3 / 10 | 44 | SEGURO |
RwLock poison .unwrap() | 1 / 10 | 30 | INVARIANTE |
Regex::new(literal).unwrap() en Lazy | 2 / 10 | 21 | INVARIANTE |
unreachable!() con guarda invariante | 3 / 10 | 11 | DOCUMENTADO |
unsafe con comentario SAFETY | 1 / 10 | 9 | DOCUMENTADO |
panic! / todo! en produccion | 0 / 10 | 0 | PASS |
Cada unwrap clasificado. Cada unsafe documentado. Cada fix verificado con tests.
Pago anticipado via Stripe. Sin hallazgos accionables? Reembolso completo.
Pago anticipado. Sin hallazgos accionables, reembolso completo.