{
 "schema": "marketnow-sentinel-benchmark/1.0",
 "generated_at": "2026-09-25T02:40:00Z",
 "name": "Sentinel v3.0 decision benchmark (public, reproducible)",
 "methodology": {
  "summary": "Matriz de confusión a nivel DECISIÓN (cuarentena / no-cuarentena) sobre corpora etiquetados públicos. Positivos = decisiones del ledger de cuarentena + incidente troyano documentado (issue #9). Negativos = 14 paquetes propios MarketNow auditados y publicados desde fuente (0 vulnerabilidades npm). Cada input es verificable por URL; ningún número es simulado.",
  "corpora": {
   "positives": {
    "n": 4,
    "records": [
     {
      "id": "qd_2026_08_15_001",
      "label": "malicious",
      "outcome": "quarantined",
      "class": "TP",
      "why": "Prompt injection en description (L1.7/L1.8/L1.9 fail)",
      "evidence": "/_data/quarantine_decisions/2026/08/2026-08-15-qd_2026_08_15_001.json"
     },
     {
      "id": "qd_2026_08_16_002",
      "label": "malicious",
      "outcome": "quarantined",
      "class": "TP",
      "why": "Mnemonic 12 palabras hardcodeado (L1.6 fail)",
      "evidence": "/_data/quarantine_decisions/2026/08/2026-08-16-qd_2026_08_16_002.json"
     },
     {
      "id": "qd_2026_08_17_003",
      "label": "benign (test fixture)",
      "outcome": "quarantined",
      "class": "FP",
      "why": "Posible api-key en fixtures — auto-declarado false positive, apelable",
      "evidence": "/_data/quarantine_decisions/2026/08/2026-08-17-qd_2026_08_17_003.json"
     },
     {
      "id": "issue-9-trojan",
      "label": "malicious",
      "outcome": "caught by L1.7 (regression vector)",
      "class": "TP (pipeline actual) / FN documentado del pipeline pre-L1.7",
      "why": "Trojan:Win64/Lazy.PGPK!MTB en zip anidado — motivó la creación de L1.7",
      "evidence": "uta-repo: lib/sentinel-l17.mjs (regression test embebido)"
     }
    ]
   },
   "negatives": {
    "n": 14,
    "records": "14 paquetes npm propios (marketnow-*, @marketnow/*, agent-trust-card) — auditados, 0 vulnerabilidades npm, publicados desde fuente. Ninguno fue puesto en cuarentena.",
    "evidence": "/api/certification-scans.json (own=true) + /api/stats.json (npm_vulnerabilities_own_packages=0)"
   }
  },
  "confusion_matrix": {
   "true_positives": 3,
   "false_positives": 1,
   "false_negatives": 0,
   "true_negatives": 14
  },
  "metrics": {
   "precision": 0.75,
   "recall": 1.0,
   "f1": 0.857,
   "n_decisions": 18
  },
  "flag_level_analysis": {
   "benign_error_findings": {
    "agent-trust-card@1.1.2": {
     "rule": "MCP-TP-002",
     "class": "false-positive (UTF-8 BOM en package.json — no es tool poisoning)",
     "verifiable": "BOM EF BB BF confirmado en el tarball npm 1.1.2"
    },
    "@marketnow/uts@2.0.1": {
     "rule": "MCP-TP-002",
     "class": "false-positive (UTF-8 BOM en package.json)",
     "verifiable": "mismo patrón BOM que agent-trust-card"
    },
    "@marketnow/trust-core@2.0.1": {
     "rule": "MCP-CI-001/MCP-AC-002",
     "class": "true-pattern/acceptable-context (execSync openssl en código de build, regexes de detección en dist)",
     "verifiable": "/api/certification?package=@marketnow/trust-core"
    },
    "@marketnow/sentinel-rules@1.0.0": {
     "rule": "PI/AC family",
     "class": "true-positive-by-design (el paquete CONTIENE las firmas de detección)",
     "verifiable": "uta-monorepo/packages/sentinel-rules/rules/rules-lite.json"
    }
   },
   "error_fp_rate_on_benign_corpus": 0.143,
   "note": "Los 2 FP error-severity son de clase BOM (EF BB BF) en package.json — remediables; los otros 2 hits son correctos por patrón. Las WARNING (SSRF-localhost, readFileSync) son de alta sensibilidad por diseño: documentadas, no silenciadas."
  },
  "limitations": [
   "n pequeño (18 decisiones totales): intervalos de confianza amplios; este benchmark mide transparencia verificable, no potencia estadística.",
   "Sesgo de corpus conocido: los negativos son paquetes propios (más limpios que la media npm).",
   "El motor L2-lite usa 22 regex exactas + 7 aproximaciones estructurales; el AST completo corre en semgrep (ver reglas).",
   "Recall=1.0 solo cubre incidentes CONOCIDOS y públicos; un atacante novel no está representado."
  ],
  "reproducibility": [
   "Ledger con SHA-256 por registro: /_data/quarantine_decisions/MANIFEST.json",
   "Scans crudos por paquete: /api/certification-scans.json",
   "Reglas (29): uta-monorepo/packages/sentinel-rules (npm @marketnow/sentinel-rules)",
   "Regenerar: python3 scripts/certify_index.py (repo)"
  ]
 },
 "urls": {
  "html": "/security/sentinel-benchmark",
  "ledger": "/_data/quarantine_decisions/MANIFEST.json",
  "scans": "/api/certification-scans.json",
  "certification": "/api/certification.json"
 }
}