---
name: proposal_from_failure
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func ProposalFromFailure(registryDB string, appID string, results []CheckResult, executionID string) ([]string, error)"
description: "Crea una fila en la tabla proposals de registry.db por cada CheckResult con Status=fail. Usa kind=new_function para fallos criticos y kind=improve_function para warnings. Retorna los IDs de proposals creados. Parte del bucle reactivo: conecta los resultados de e2e_run_checks con la etapa MEJORAR."
tags: [proposals, reactive-loop, e2e, monitoring, registry, infra, pendiente-usar]
uses_functions: [random_hex_id_go_core, sqlite_open_go_infra]
uses_types: [CheckResult_go_infra]
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [crypto/rand, encoding/hex, encoding/json, fmt, time, database/sql]
tested: true
tests:
  - "no inserta nada cuando todos los checks pasan"
  - "inserta proposal por cada check fallido"
  - "proposal critica usa kind new_function"
  - "proposal warning usa kind improve_function"
  - "proposals tienen timestamp reciente"
test_file_path: "functions/infra/proposal_from_failure_test.go"
file_path: "functions/infra/proposal_from_failure.go"
params:
  - name: registryDB
    desc: "Path absoluto o relativo a registry.db. Puede ser ':memory:' en tests."
  - name: appID
    desc: "ID del artefacto (app) al que pertenecen los checks. Se guarda como target_id en la proposal."
  - name: results
    desc: "Lista de CheckResult de e2e_run_checks_go_infra. Solo los con Status=fail generan proposals."
  - name: executionID
    desc: "ID de la ejecucion en operations.db. Se incluye en el campo evidence de la proposal para trazabilidad."
output: "Lista de IDs de proposals creados (formato 'prop_<16hexchars>'). Error si no se puede abrir la BD o falla algun INSERT."
---

## Ejemplo

```go
results, _ := infra.E2ERunChecks(checks, "/opt/apps/myapp")
propIDs, err := infra.ProposalFromFailure(
    "$HOME/fn_registry/registry.db",
    "my_app",
    results,
    "exec_20260509_001",
)
// propIDs = ["prop_a1b2c3d4e5f6a7b8", ...]
// Cada ID insertado en proposals con status=pending, created_by=reactive_loop
```

## Mapeo de severity a kind de proposal

| Severity del check | kind en proposals |
|---|---|
| `critical` | `new_function` (proxy de mayor urgencia) |
| `warning` | `improve_function` |

**Nota de diseno:** el schema de `proposals` limita `kind` a
`(new_function, new_type, improve_function, improve_type, new_pipeline)`.
No existe `bug` ni `optimization`. Se usan `new_function` e `improve_function`
como proxies hasta que se extienda el schema con un migration.
Para un futuro migration: `ALTER TABLE proposals ADD COLUMN ...` o
añadir `bug` y `optimization` al CHECK constraint en `migrations/NNN_add_bug_kind.sql`.

## Notas

La funcion abre y cierra la conexion a registry.db en cada llamada. Para uso frecuente
dentro de una sesion larga, considerar pasar una `*sql.DB` abierta como variante futura.

El campo `evidence` de la proposal contiene JSON con:
`{check_id, execution_id, exit_code, error, severity}` para debugging posterior.
