{
 "about": {
  "method": "ki-cheng-prusoff-bounds",
  "origin": "Hand-chosen values; exact rational arithmetic",
  "ruling": "CSO memo of 11 October 2026, item 8 (docs/board/memos/2026-10-11-cso-assay-depth-stage.md); roadmap A5",
  "label": "the IC50's bounds through the equation; Km and [S] treated as exact",
  "reference": "Cheng Y, Prusoff WH (1973). Biochem Pharmacol 22:3099-3108. doi:10.1016/0006-2952(73)90196-2 (record and abstract read 10 October 2026)",
  "tolerances": {
   "ki, low and high": "within 1e-12 relative",
   "shown": "exact (four significant figures)",
   "refusals and bounds states": "exact; no number"
  },
  "recordedOn": "2026-10-13",
  "script": "pipeline/assay-analyser/oracles/ki_bounds.py",
  "scriptSha256": "51255994e2b0839540878aeeb5a4832d762df5daf3fc9b1a1eb4164de55eac19",
  "helper": {
   "script": "pipeline/assay-analyser/oracles/stage_a_oracle.py",
   "sha256": "492d85ca2fa6750db80b1c64214fd4a0b13cd4c588267244f6262c504c73e3e8"
  },
  "environment": {
   "image": "ghcr.io/biotechmat/drybench/oracle-env:11b8a5e4456df7eb@sha256:7e69891ca1d9f24838660e0a9887bdb654ce7771d2f2ac7e7275e9b1eb3b6a09",
   "r": "R version 4.4.3 (2025-02-28)",
   "packages": {},
   "python": "3.11.15",
   "numpy": "2.0.2",
   "scipy": "1.13.1",
   "recordedOn": "2026-10-13",
   "cpu": "AMD EPYC 7763 64-Core Processor",
   "cpuClass": "x86-64-v3",
   "simd": [
    "SSSE3",
    "SSE41",
    "POPCNT",
    "SSE42",
    "AVX",
    "F16C",
    "FMA3",
    "AVX2"
   ],
   "openblasCore": "Haswell",
   "threads": 1
  },
  "crossCheck": {
   "tool": "R",
   "ran": false,
   "reason": "Exact rational arithmetic is the oracle (the published ki-cheng-prusoff.json's method); no R cross-check is named"
  }
 },
 "oracle": {
  "engine": "Python fractions and decimal"
 },
 "cases": [
  {
   "name": "s-equals-km",
   "about": "[S] = Km halves the IC50 and both bounds",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": "80",
   "ic50High": "125",
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "computed",
     "low": 40.0,
     "high": 62.5,
     "lowExact": "40/1",
     "highExact": "125/2",
     "lowShown": "40.00",
     "highShown": "62.50"
    }
   }
  },
  {
   "name": "s-zero",
   "about": "[S] = 0: the bounds unchanged",
   "ic50": {
    "value": "250",
    "unit": "nM"
   },
   "substrate": {
    "value": "0",
    "unit": "µM"
   },
   "km": {
    "value": "12",
    "unit": "µM"
   },
   "ic50Low": "200",
   "ic50High": "310",
   "expected": {
    "ok": true,
    "ki": 250.0,
    "kiExact": "250/1",
    "shown": "250.0",
    "unit": "nM",
    "bounds": {
     "status": "computed",
     "low": 200.0,
     "high": 310.0,
     "lowExact": "200/1",
     "highExact": "310/1",
     "lowShown": "200.0",
     "highShown": "310.0"
    }
   }
  },
  {
   "name": "mixed-prefixes",
   "about": "[S] in mM and Km in µM: 1 + 2.5/0.8",
   "ic50": {
    "value": "37",
    "unit": "nM"
   },
   "substrate": {
    "value": "2.5",
    "unit": "mM"
   },
   "km": {
    "value": "800",
    "unit": "µM"
   },
   "ic50Low": "29.5",
   "ic50High": "46.1",
   "expected": {
    "ok": true,
    "ki": 8.969696969696969,
    "kiExact": "296/33",
    "shown": "8.970",
    "unit": "nM",
    "bounds": {
     "status": "computed",
     "low": 7.151515151515151,
     "high": 11.175757575757576,
     "lowExact": "236/33",
     "highExact": "1844/165",
     "lowShown": "7.152",
     "highShown": "11.18"
    }
   }
  },
  {
   "name": "repeating",
   "about": "A non-terminating factor, 1 + 10/3",
   "ic50": {
    "value": "1",
    "unit": "µM"
   },
   "substrate": {
    "value": "10",
    "unit": "µM"
   },
   "km": {
    "value": "3",
    "unit": "µM"
   },
   "ic50Low": "0.7",
   "ic50High": "1.4",
   "expected": {
    "ok": true,
    "ki": 0.23076923076923078,
    "kiExact": "3/13",
    "shown": "0.2308",
    "unit": "µM",
    "bounds": {
     "status": "computed",
     "low": 0.16153846153846155,
     "high": 0.3230769230769231,
     "lowExact": "21/130",
     "highExact": "21/65",
     "lowShown": "0.1615",
     "highShown": "0.3231"
    }
   }
  },
  {
   "name": "no-bounds",
   "about": "No bounds typed: the Ki alone",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": null,
   "ic50High": null,
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "none"
    }
   }
  },
  {
   "name": "bound-equals-ic50",
   "about": "A degenerate lower bound equal to the IC50 is accepted",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": "100",
   "ic50High": "150",
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "computed",
     "low": 50.0,
     "high": 75.0,
     "lowExact": "50/1",
     "highExact": "75/1",
     "lowShown": "50.00",
     "highShown": "75.00"
    }
   }
  },
  {
   "name": "refused-one-bound",
   "about": "Only the lower bound typed",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": "80",
   "ic50High": null,
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "refused",
     "problem": "bounds-incomplete"
    }
   }
  },
  {
   "name": "refused-order",
   "about": "Bounds that do not contain the IC50",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": "120",
   "ic50High": "150",
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "refused",
     "problem": "bounds-order"
    }
   }
  },
  {
   "name": "refused-zero-bound",
   "about": "A lower bound of zero",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "50",
    "unit": "µM"
   },
   "ic50Low": "0",
   "ic50High": "150",
   "expected": {
    "ok": true,
    "ki": 50.0,
    "kiExact": "50/1",
    "shown": "50.00",
    "unit": "nM",
    "bounds": {
     "status": "refused",
     "problem": "bounds-range"
    }
   }
  },
  {
   "name": "refused-ki-units",
   "about": "[S] and Km in different dimensions: no Ki, so no bounds",
   "ic50": {
    "value": "100",
    "unit": "nM"
   },
   "substrate": {
    "value": "50",
    "unit": "µM"
   },
   "km": {
    "value": "5",
    "unit": "µg/mL"
   },
   "ic50Low": "80",
   "ic50High": "125",
   "expected": {
    "ok": false,
    "problem": "units"
   }
  }
 ]
}
