/- GeneticsPromotionGate.lean — Mass Number Gate for Genetics Model Promotion Wires the core MassNumber admissibility gate into genetics-specific promotion. Every genetics model must pass this gate before being promoted from REGISTRY_ONLY → CANONICAL_PLUMBED. Gate criteria: 1. MassLeDefault (admissible <= threshold * guarded_residual) 2. depth <= 2 (no deep abstraction recursion in biological claims) 3. boundCheck = true (must declare data source and validation plan) 4. biological_equivalence_check (must not claim DNA equivalence without receipt) 5. taxonomy_gap_fill (must declare which GCCL group it covers) Reference: - Semantics/Core/MassNumber.lean (three-layer gate) - otom/docs/genetics_information_substrate_boundary.md (four buckets) -/ import Semantics.Core.MassNumber namespace Semantics.GeneticsPromotionGate open Q16_16 /- ============================================================================ §0 Genetics-Specific Promotion Criteria ============================================================================ -/ /-- Which GCCL taxonomy group this model claims to cover. Must be explicit — "none" is allowed but means the model is generic. -/ inductive GCCLGroup | A_molecular_alphabets | B_codon_translation | C_protein_peptide | D_ambiguity_degeneracy | E_sequence_file_quality | F_alignment_assembly_graph | G_variant_haplotype_population | H_annotation_feature | I_epigenetic_regulatory | J_structural_3d_genome | K_expression_multi_omics | L_compression_indexing | M_synthetic_expanded | N_gccl_native | none deriving Repr, Inhabited, DecidableEq, BEq /-- A genetics model's self-declared coverage and claim state. -/ structure GeneticsClaim where modelName : String gcclGroup : GCCLGroup hasRealData : Bool -- Does it use biological data (gnomAD, NCBI, etc.)? hasLeanProof : Bool -- Is there a compiled Lean module? hasPythonImpl: Bool -- Is there a running Python script? hasDataReceipt: Bool -- Does it declare data source + validation plan? claimsBiologicalEquivalence : Bool -- Dangerous: claims "GCCL is DNA" etc. deriving Repr, Inhabited /-- Default claim for a new model (conservative, no claims). -/ def defaultClaim (name : String) : GeneticsClaim := { modelName := name , gcclGroup := .none , hasRealData := false , hasLeanProof := false , hasPythonImpl := false , hasDataReceipt := false , claimsBiologicalEquivalence := false } /- ============================================================================ §1 The Genetics Promotion Gate ============================================================================ -/ /-- Calculate admissible reduction for a genetics model. Scoring: - hasLeanProof: +3 (formalization is high value) - hasPythonImpl: +2 (running code is medium value) - hasRealData: +2 (grounding in biology is medium value) - hasDataReceipt: +1 (hygiene is low but necessary) - fillsZeroGroup: +2 (filling a gap is valuable) - claimsBiologicalEquivalence: -10 (heavily penalized) -/ def admissibleReduction (claim : GeneticsClaim) (fillsZeroGroup : Bool) : Q16_16 := let withLean := if claim.hasLeanProof then Q16_16.ofNat 3 else Q16_16.zero let withPython := if claim.hasPythonImpl then Q16_16.ofNat 2 else Q16_16.zero let withData := if claim.hasRealData then Q16_16.ofNat 2 else Q16_16.zero let withReceipt := if claim.hasDataReceipt then Q16_16.ofNat 1 else Q16_16.zero let withGapFill := if fillsZeroGroup then Q16_16.ofNat 2 else Q16_16.zero let penalty := if claim.claimsBiologicalEquivalence then Q16_16.ofInt (-10) else Q16_16.zero withLean + withPython + withData + withReceipt + withGapFill + penalty /-- Calculate residual risk for a genetics model. Scoring (higher = more risk): - !hasLeanProof: +2 (unformalized = risk) - !hasPythonImpl: +1 (no running code = some risk) - !hasDataReceipt: +3 (no validation plan = high risk) - claimsBiologicalEquivalence: +5 (dangerous claim = very high risk) - depth > 0: +1 per depth (abstraction recursion risk) -/ def residualRisk (claim : GeneticsClaim) (depth : Nat) : Q16_16 := let noLean := if !claim.hasLeanProof then Q16_16.ofNat 2 else Q16_16.zero let noPython := if !claim.hasPythonImpl then Q16_16.ofNat 1 else Q16_16.zero let noReceipt := if !claim.hasDataReceipt then Q16_16.ofNat 3 else Q16_16.zero let bioClaim := if claim.claimsBiologicalEquivalence then Q16_16.ofNat 5 else Q16_16.zero let depthRisk := Q16_16.ofNat depth noLean + noPython + noReceipt + bioClaim + depthRisk /-- The genetics promotion gate. Parameters: claim : the model's self-declared claim state fillsZeroGroup: does this model fill a zero-coverage GCCL group? depth : recursion depth of abstraction (default 0) threshold : promotion boundary (default 0.5 = generous) Returns true iff the model is admissible for promotion. -/ def geneticsPromotionGate (claim : GeneticsClaim) (fillsZeroGroup : Bool) (depth : Nat := 0) (threshold : Q16_16 := Q16_16.ofRatio 1 2) : Bool := let a := admissibleReduction claim fillsZeroGroup let r := residualRisk claim depth -- Promotion gate: quality must EXCEED threshold * risk -- (MassLe is designed for cost<=threshold*risk compression decisions; -- genetics promotion needs quality>threshold*risk) let qualityBeatsRisk := a.toInt > (threshold * r).toInt let depthOk := depth ≤ 2 let receiptOk := claim.hasDataReceipt qualityBeatsRisk && depthOk && receiptOk /-- Warden rule: if a model claims biological equivalence without receipt, emit Underverse packet and block promotion. -/ def biologicalEquivalenceWarden (claim : GeneticsClaim) : String := if claim.claimsBiologicalEquivalence && !claim.hasDataReceipt then "UNDERVERSE: biological_equivalence_without_receipt — model " ++ claim.modelName ++ " blocked" else "PASS" /- ============================================================================ §2 Audit Existing Canonical Models ============================================================================ -/ /-- Claim state for GeneticCode.lean -/ def geneticCodeClaim : GeneticsClaim := { defaultClaim "GeneticCode.lean" with gcclGroup := .B_codon_translation , hasLeanProof := true , hasDataReceipt := true -- NCBI Table 1 is well-documented } /-- Claim state for CodonOTOM.lean -/ def codonOTOMClaim : GeneticsClaim := { defaultClaim "CodonOTOM.lean" with gcclGroup := .B_codon_translation , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for PeptideMoE.lean -/ def peptideMoEClaim : GeneticsClaim := { defaultClaim "PeptideMoE.lean" with gcclGroup := .C_protein_peptide , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for GenomicCompression.lean -/ def genomicCompressionClaim : GeneticsClaim := { defaultClaim "GenomicCompression.lean" with gcclGroup := .L_compression_indexing , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for SyntheticGeneticCoding.lean -/ def syntheticGeneticCodingClaim : GeneticsClaim := { defaultClaim "SyntheticGeneticCoding.lean" with gcclGroup := .M_synthetic_expanded , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for GeneticGroundUp.lean -/ def geneticGroundUpClaim : GeneticsClaim := { defaultClaim "GeneticGroundUp.lean" with gcclGroup := .N_gccl_native , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for HachimojiPipeline.lean -/ def hachimojiClaim : GeneticsClaim := { defaultClaim "HachimojiPipeline.lean" with gcclGroup := .M_synthetic_expanded , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for CodonPeptideConsistency.lean -/ def codonPeptideConsistencyClaim : GeneticsClaim := { defaultClaim "CodonPeptideConsistency.lean" with gcclGroup := .B_codon_translation , hasLeanProof := true , hasDataReceipt := true } /-- Claim state for Allelica.py (Python script on real data) -/ def allelicaClaim : GeneticsClaim := { defaultClaim "Allelica.py" with gcclGroup := .G_variant_haplotype_population , hasRealData := true , hasPythonImpl := true , hasDataReceipt := true -- gnomAD source declared } /-- Run the promotion gate on all canonical models. This is the infrastructure test: it reveals which models pass/fail. -/ def auditCanonicalModels : String := let models := [ ("GeneticCode.lean", geneticCodeClaim, false) , ("CodonOTOM.lean", codonOTOMClaim, false) , ("PeptideMoE.lean", peptideMoEClaim, false) , ("GenomicCompression.lean", genomicCompressionClaim, false) , ("SyntheticGeneticCoding.lean", syntheticGeneticCodingClaim, false) , ("GeneticGroundUp.lean", geneticGroundUpClaim, false) , ("HachimojiPipeline.lean", hachimojiClaim, false) , ("CodonPeptideConsistency.lean", codonPeptideConsistencyClaim, false) , ("Allelica.py", allelicaClaim, false) ] let results := models.map (fun (name, claim, fillsZero) => let passes := geneticsPromotionGate claim fillsZero let warden := biologicalEquivalenceWarden claim let aInt := (admissibleReduction claim fillsZero).toInt let rInt := (residualRisk claim 0).toInt s!"{name}: passes={passes} | warden={warden} | a={aInt} | r={rInt}" ) String.intercalate "\n" results #eval! auditCanonicalModels /- ============================================================================ §3 Audit REGISTRY_ONLY Models (Should Fail Gate) ============================================================================ -/ /-- Claim state for a typical REGISTRY_ONLY model (no implementation). -/ def registryOnlyClaim (name : String) (group : GCCLGroup) : GeneticsClaim := { defaultClaim name with gcclGroup := group , hasDataReceipt := false -- No implementation = no validation plan } /-- Run the gate on REGISTRY_ONLY models to confirm they fail. This demonstrates the gate is working: unimplemented models are blocked. -/ def auditRegistryOnlyModels : String := let models := [ ("Hardy-Weinberg (registry)", registryOnlyClaim "Hardy-Weinberg" .G_variant_haplotype_population, false) , ("Wright-Fisher Drift (registry)", registryOnlyClaim "Wright-Fisher" .G_variant_haplotype_population, true) -- fills zero group , ("RNA Folding deltaG (registry)", registryOnlyClaim "RNA_Folding" .C_protein_peptide, true) -- fills zero group F , ("Jukes-Cantor (registry)", registryOnlyClaim "JukesCantor" .D_ambiguity_degeneracy, false) , ("Quasispecies (ghost)", registryOnlyClaim "Quasispecies" .L_compression_indexing, false) ] let results := models.map (fun (name, claim, fillsZero) => let passes := geneticsPromotionGate claim fillsZero let a := admissibleReduction claim fillsZero let r := residualRisk claim 0 let aInt := a.toInt let rInt := r.toInt s!"{name}: passes={passes} | a={aInt} | r={rInt}" ) String.intercalate "\n" results #eval! auditRegistryOnlyModels /- ============================================================================ §4 Gate Configuration ============================================================================ -/ /-- Threshold configuration for different promotion contexts. -/ def conservativeThreshold : Q16_16 := Q16_16.ofRatio 3 10 -- 0.3: strict def defaultThreshold : Q16_16 := Q16_16.ofRatio 1 2 -- 0.5: normal def generousThreshold : Q16_16 := Q16_16.ofRatio 7 10 -- 0.7: lenient /-- Which threshold to use for which context. -/ def thresholdFor (context : String) : Q16_16 := if context == "conservative" then conservativeThreshold else if context == "generous" then generousThreshold else defaultThreshold end Semantics.GeneticsPromotionGate