# BioTwin Accelerator — Checklist v0.2 (typed evidence)

*Supersedes v0.1. Every gate is now an instance of the shared `EvidenceType`
schema in §0 — the same schema the composites accelerator imports — so the two
accelerators share one machine-checkable type system instead of two prose
checklists. Refusals are **derived** from the admissibility law, not hand-listed.*

**Standing boundary:** generates mechanism hypotheses, ranks the next experiment,
bounds its own uncertainty. Does **not** make clinical decisions; every
patient-facing output defers to the treating clinician, basis visible and
override-able. `authorizes_action = false` everywhere.

**The one axiom (everything below is a corollary):**
> An operation is **admissible** iff it is a *homomorphism* for the declared
> algebra of every input's type. The result's **posture** is the **meet** of the
> inputs' postures, **lowered by the functor-class** of the operation. `meet` is
> `min` on the cube ladder (the tropical semiring).

---

## §0 — Shared type system (`forza/evidence_types` — imported by both accelerators)

```python
# The canonical evidence type. Composites and BioTwin are INSTANCES of this,
# not separate schemas. This block is the shared machine-checkable core.

EvidenceType = {
  "id":            str,
  "geometry":      Enum("euclidean","log_ratio","circular_torus","sphere_SO3",
                        "simplex_aitchison","sequence_free_monoid","graph",
                        "ordinal_lattice"),
  "statistic":     Enum("mean","median_band","lower_tail","upper_tail","moments",
                        "quantiles","threshold","order_preserving","cardinality"),
  "grain":         "position on a declared partial order (lattice)",   # directional
  "rev":           "resolution at which CWA/closure is valid",
  "conservation":  str,          # quantity a merge must preserve (mass, unit-norm, ...)
  "merge":         "the value monoid (how VALUES compose)",
  "merge_commutative": bool,     # 'mergeable sketch' == commutative monoid
  "merge_idempotent":  bool,     # A(+)A==A? set-union yes; pooled-survival NO
  "uncertainty":   Enum("variance_add","tangent_cov","tolerance_bound_conf",
                        "conformal_coverage","composed_lax_error"),  # how BOUNDS compose
  "failure_mechanism": str,      # UPSTREAM of statistic (mechanism selects statistic)
  "functor_default":   Enum("strict","lax","anti"),
  "posture_cap":   Enum("refused","unknown","candidate","certified","reconciled"),
  "forbidden":     "DERIVED = the non-homomorphisms for (geometry, merge)",
}

def well_formed(t) -> bool:
    # internal consistency of ONE object's tuple
    return (statistic_consistent_with(t.failure_mechanism, t.statistic)
            and merge_is_homomorphism(t.geometry, t.merge)
            and merge_preserves(t.conservation))

def functor_class(op) -> "strict|lax|anti":
    # relabel/exact -> strict ; homogenize up-grain -> lax ;
    # disaggregate / allocate / counterfactual (manufacture finer structure) -> anti
    ...

def admissible(op, inputs) -> bool:
    return (all(is_homomorphism(op, x.type) for x in inputs)     # structure preserved
            and meet_types(inputs) is not BOTTOM)                # compatible (grain/geom/stat)

def result_posture(op, inputs):
    p = meet_posture(inputs)                 # = min on the cube ladder (tropical)
    return lower_by(p, functor_class(op))    # anti lowers hardest; strict preserves
```

`meet_types` returns `BOTTOM (⊥)` when geometries differ and neither lifts, when
grains sit on incompatible lattices, or when the requested op is off the type's
support (e.g. positivity fails). `⊥ ⇒ WITHHOLD`. Every refusal in this file is
one of these three, not a remembered rule.

---

## §1–§10 — Gates as typed evidence objects

```yaml
# Gate 1 — Molecular identity & grain
type: molecular_identity
geometry: ordinal_lattice
statistic: n/a                     # identity, not a summary
grain: atomistic < residue < domain < protein < complex < cell < patient
conservation: entity_identity
merge: exact_match
merge_commutative: true;  merge_idempotent: true
functor_default: strict
posture_cap: certified
forbidden: [compare_across_grain, compare_across_binding_mechanism]
# CATCH: ATP-competitive (imatinib) and allosteric-STAMP (asciminib) are
# DIFFERENT TYPES -> meet = ⊥. Never share a committor/model across mechanisms.
```

```yaml
# Gate 2 — Structure & folding   (emits several typed objects)
type: dihedral_ensemble
geometry: circular_torus           # phi/psi live on a torus
statistic: moments                 # von Mises
grain: residue
conservation: none
merge: circular_mean
merge_commutative: true;  merge_idempotent: true(set) / false(weighted)
uncertainty: tangent_cov           # concentration, not scalar variance
functor_default: lax
posture_cap: certified
forbidden: [arithmetic_mean, euclidean_interpolation]   # DERIVED: not homs on S1
---
type: backbone_orientation
geometry: sphere_SO3
merge: orientation_tensor
forbidden: [arithmetic_mean, euclidean_interpolation]
---
type: contact_map
geometry: graph
statistic: threshold
merge: graph_union
# CATCH: Euclidean-averaging angles is the SAME launder as averaging fiber
# orientation in composites. pLDDT/PAE ride along as a declared-loss field.
```

```yaml
# Gate 3 — Binding & kinetics (TST)
type: binding_deltaG_rate
geometry: log_ratio                # k = exp(-dG/RT) is multiplicative
statistic: lower_tail              # safety is tail-governed
grain: complex
conservation: detailed_balance     # k_f/k_r = K_eq (metamorphic oracle)
merge: log_space_pool
uncertainty: tolerance_bound_conf
failure_mechanism: barrier_crossing
functor_default: lax
posture_cap: candidate             # -> certified only via kappa-ledger + RC validation
forbidden: [linear_mean_of_rates]  # DERIVED: not a hom on log_ratio  (use DDSketch, not KLL)
# GATE: spectral_gap present -> single kinetic story admissible;
#       absent -> report interval, escalate grain (the ensemble case is the norm).
```

```yaml
# Gate 4 — PK/PD bridge   [the molecular->patient operator; MANDATORY]
type: pkpd_bridge
geometry: log_ratio                # concentrations; compartments
statistic: median_band + lower_tail(safety)
grain: molecule -> patient         # this operator IS the up-grain step
rev: patient
conservation: mass_balance         # dose accounting
merge: compartment_compose
uncertainty: composed_lax_error
functor_default: lax               # bridges grain up; posture degrades with model error
posture_cap: candidate             # -> certified only against measured trough/response
# CATCH: any molecular-grain evidence merged with patient-grain evidence has
# meet = ⊥ UNLESS routed through this object. No skipping the bridge.
```

```yaml
# Gate 5 — Dynamics & network (MSM)
type: conformational_msm
geometry: graph                    # stochastic transition matrix
statistic: threshold + moments     # dwell times, eigenvalues
grain: microstate -> metastable    # PCCA+ coarse-grain
merge: count_pool
merge_idempotent: false            # adding the SAME trajectory twice inflates counts
uncertainty: composed_lax_error
functor_default: lax
posture_cap: candidate
forbidden: [merge_without_markov_order_test]   # Anderson-Goodman gate first
# GATE: spectral_gap = metastability certificate = the validity of a single rate.
```

```yaml
# Gate 6 — Causal / counterfactual   [THE ANTI-FUNCTOR OPERATION — see §6 below]
type: counterfactual_claim
geometry: n/a (an OPERATION, do(.), not a summary)
functor_default: anti              # manufactures a road-not-taken from one observed road
posture_cap: candidate             # <= posture of the SCM it rides on (Gate 4 kappa-ledger)
default_verdict: withhold
```

```yaml
# Gate 7 — Patient / phenotypic bridging
type: transcript_trajectory        # BCR-ABL1 on the International Scale
geometry: log_ratio                # response is DEFINED in logs (MMR/MR4/MR4.5)
statistic: lower_tail              # deep response = tail
grain: patient
merge: log_space_pool
merge_idempotent: false            # pooling the SAME blood draw twice falsely tightens CI
uncertainty: tolerance_bound_conf -> conformal
functor_default: lax
posture_cap: certified
forbidden: [linear_tdigest, double_count]   # DDSketch, not KLL; idempotency guard
---
type: hrv_wearable
geometry: log_ratio + circular     # lnRMSSD + phase
evidence_tier: LOW                 # consumer device; noisy, device-dependent
posture_cap: candidate             # may not launder up to a clinical signal
---
privacy: single_patient_twin IS PHI
merge_cross_patient: requires differential_privacy   # else leakage functor fires
```

```yaml
# Gate 8 — Evidence type & validation
tier_lattice: clinical_assay > cell_line > in_vitro > wearable
merge_rule: meet floors to the WEAKER tier
validation: analytical_validation (reconstruction) vs clinical_validation (outcome)
ladder: in_silico < in_vitro < cell < (animal) < retrospective_match < prospective_n_of_1
claim_rule: an object claims only up to its highest VALIDATED rung
```

```yaml
# Gate 9 — Conformal calibration   [safety-critical]
type: calibrated_interval
uncertainty: conformal_coverage
n1_rule: conformal_under_covariate_shift (weighted/Mondrian)   # she is not the cohort
posture_cap: certified             # ONLY if measured coverage >= declared coverage
# NOTE: the covariate-shift edge here is the SAME object as Gate 6's
# transportability edge (a selection-diagram arrow). Gate 9 and Gate 6 merge.
```

```yaml
# Gate 10 — Authority boundary
ladder->posture:
  mechanism_insight       -> candidate
  hypothesis + next_test  -> candidate (+ MEO probe attached)
  counterfactual          -> anti-functor (see §6); default withhold
  subpopulation_validated -> certified (cohort only)
  this_patient_support    -> reconciled (clinician-in-loop, basis visible, override-able)
outside_validated_envelope: meet = ⊥ -> WITHHOLD    # e.g. ~22y exposure extrapolation
authorizes_action: false
```

---

## §6 — Gate 6 as the anti-functor operation `do(strategy)`

A counterfactual manufactures a road-not-taken (finer structure) from a single
observed road, so it is an **anti-functor**: posture **floors down** by
construction and is admissible only through a validated model whose `kappa-ledger`
caps it. Concretely:

```yaml
operation: do(strategy)            # e.g. do(asciminib, dose, schedule)
functor_class: anti
admissible_iff: ONE of
  (a) validated mechanistic SCM      # abduction -> action -> prediction
      posture <= SCM.kappa_ledger    # never more certified than the mechanism
  (b) target_trial_emulation with assumptions CHECKED   # -> target_trial_boundary.py
  else: REFUSE and emit n_of_1_design            # the MEO/value-of-information tail

time_varying_rule:                  # CML is chronic: dose_t -> transcript_t -> dose_{t+1}
  grain_time_lattice: directional (treatment-confounder feedback)
  ONLY_homomorphic_merge: g_method  # marginal structural model / IPTW / g-formula
  forbidden: naive_adjustment       # not a hom on the time lattice -> points WRONG way

assumptions_as_refusals:            # each is a meet=⊥ or a required declaration
  consistency_SUTVA: strategy must be a concrete dose+schedule      # else ⊥
  positivity_overlap: no support (e.g. rare T315I profile) -> ⊥ -> withhold
  exchangeability:  unverifiable -> BOUND it: report E-value + negative_controls
                    if a plausible confounder (adherence) flips the sign -> refuse
  transportability: covariate-shift edge declared + reweighted       # == Gate 9

refutation_before_emit:             # DoWhy-style refuters; survive to earn posture
  [placebo_treatment, random_common_cause, subset_stability, unobserved_confounder_sens]

output_shape:                       # non-device CDS: clinician can inspect + override
  mechanistic_counterfactual + E_value + assumptions + confirming_n_of_1_design
```

---

## §Overlap — one type system, two accelerators (the consolidation)

The point of v0.2: composites and BioTwin are now **instances of the same
types**, so the shared engines are literal, not analogical.

| Shared `EvidenceType` | Composites instance | BioTwin instance |
|---|---|---|
| `geometry:lower_tail` + `uncertainty:tolerance/conformal` | strength -> CMH-17 A/B-basis | occupancy / toxicity -> conformal-under-shift |
| `geometry:sphere_SO3`, `merge:orientation_tensor` | fiber ODF (Advani-Tucker) | backbone orientation |
| `geometry:sequence_free_monoid`, order-preserving | layup schedule (CLT D-matrix) | peptide / residue sequence |
| `geometry:graph`, `statistic:threshold` | connectivity / percolation | contact map / MSM |
| `functor:anti` | allocation / disaggregation | **`do()` counterfactual** |
| `merge_idempotent:false` guard | pooled coupon survival | pooled blood-draw / trajectory |

**The one muscle both still need** is the `lower_tail`/`tolerance` type's engine:
build `tail_uncertainty` once (weakest-link -> lower-tolerance-bound -> conformal),
register it against `geometry:lower_tail`, and both accelerators inherit it — CMH-17
for composites, conformal-under-shift for the patient.

---

**Status:** v0.2 — typed. Both files should now `import forza/evidence_types` (§0)
rather than restate a checklist.
**Next:** point `COMPOSITES_SKETCHING_AND_EVIDENCE_CHECKLIST.md` at the same §0,
and implement `well_formed` + `meet_types` so the refusals run instead of read.
