pen-stack 5.5.0__tar.gz → 5.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pen_stack-5.5.0 → pen_stack-5.6.0}/CHANGELOG.md +34 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/CITATION.cff +2 -2
- {pen_stack-5.5.0 → pen_stack-5.6.0}/PKG-INFO +42 -9
- {pen_stack-5.5.0 → pen_stack-5.6.0}/README.md +41 -8
- pen_stack-5.6.0/configs/antipeg.yaml +28 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/known_unknowns.yaml +27 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/oracles/scope_cards.yaml +13 -0
- pen_stack-5.6.0/docs/delivery_immunology.md +150 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/index.md +1 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/__init__.py +1 -1
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/cite.py +9 -0
- pen_stack-5.6.0/pen_stack/planner/antipeg_oracle.py +75 -0
- pen_stack-5.6.0/pen_stack/planner/immune_profile.py +98 -0
- pen_stack-5.6.0/pen_stack/validate/immune_calibration.py +122 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/schema.py +3 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/service.py +14 -1
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/PKG-INFO +42 -9
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/SOURCES.txt +11 -0
- pen_stack-5.6.0/prereg/SHA256_LOCK_ws_calib.json +8 -0
- pen_stack-5.6.0/prereg/SHA256_LOCK_ws_peg.json +8 -0
- pen_stack-5.6.0/prereg/SHA256_LOCK_ws_profile.json +8 -0
- pen_stack-5.6.0/prereg/ws_calib.yaml +28 -0
- pen_stack-5.6.0/prereg/ws_peg.yaml +31 -0
- pen_stack-5.6.0/prereg/ws_profile.yaml +32 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pyproject.toml +1 -1
- {pen_stack-5.5.0 → pen_stack-5.6.0}/LICENSE +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/MANIFEST.in +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/bench/run.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/atlas_families.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/cargo_polish.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/cell_types.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/datasets.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_rules.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/gates_v3.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/genotoxicity_oracle.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/intent_weights.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/llm.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/monitor_queries.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/delivery.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/fold.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/payload.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/reachability.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/score_axes.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/seroprevalence.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/target_sites.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/write_types.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/BACKLOG.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/DEPLOY.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/INFRA.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/MCP.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/RELEASING.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/REPRO.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/agent.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/benchmark_circularity.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/atlas.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/durability.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/safety.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/co_scientist.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/delivery.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/dissemination.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/environment.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/oracles.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/positioning.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/private_data_formats.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/quickstart.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/rules.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/scope.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/scorecard.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/uncertainty.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/verify.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/world_model.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/writer_verification.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/wtkb.md +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/_resources.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/epistemic.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/mcp_server.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/orchestrator.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/scope.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/tools.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/crosslink.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/cli.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/encode.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/genome.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_safety_annot.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/policies.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/build.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/query.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/schema.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/run.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/schema.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/structure.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/genotoxicity_oracle.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/optimize.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/pipeline.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/router.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/index.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/llm.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/qa.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/evaluators.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/loader.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/schema.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/solver.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/server/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/server/api.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/ui/app.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper3_benchmark.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/requires.txt +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper1.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper2.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper3.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper4.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/phase0.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_a.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_b.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_bench.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_c.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_cal.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_cite.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_crit.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ct.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_d.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_e.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_env.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ep.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_f.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_g.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_graph.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_h.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_immune.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_innate.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_mc.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_mon.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_o.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_plan.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_r.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_route.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_uq.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_v.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_wv.yaml +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_build_durability.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_train_safety.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_validation_report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p52_build_genotox_oracle.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/ws_b_report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/ws_c_report.py +0 -0
- {pen_stack-5.5.0 → pen_stack-5.6.0}/setup.cfg +0 -0
|
@@ -3,6 +3,40 @@
|
|
|
3
3
|
All notable changes to PEN-STACK are documented here. This file follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/) and the program's phase structure.
|
|
5
5
|
|
|
6
|
+
## [5.6.0] - 2026-06-11 - v5.6 release: Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
|
|
7
|
+
|
|
8
|
+
Finishes the delivery-immunology arc (v5.1–v5.5): adds the missing **anti-PEG** axis, **calibrates** the
|
|
9
|
+
proxies honestly, and exposes a **unified per-design immune-risk profile** that never collapses into one number.
|
|
10
|
+
Workstreams WS-{PEG,CALIB,PROFILE} (+ optional WS-EXT), SHA-locked.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **WS-PEG** — `pen_stack/planner/antipeg_oracle.py` + `configs/antipeg.yaml`: pre-existing/induced anti-PEG
|
|
14
|
+
antibodies gate **re-dosing** of PEGylated LNP. Population prevalence range (25–72 %) →
|
|
15
|
+
`preexisting_antipeg_score = 1 − midpoint/100`, range surfaced as `native_uncertainty`; **abstains** for
|
|
16
|
+
non-PEGylated vehicles. Serosurvey DOIs Crossref-verified (Chen 2016 `10.1021/acs.analchem.6b03109`, Yang &
|
|
17
|
+
Lai `10.1002/wnan.1339`, Armstrong `10.1002/cncr.22739`, Kozma `10.1016/j.addr.2020.07.024`). Scope card `antipeg`.
|
|
18
|
+
- **WS-CALIB** — `pen_stack/validate/immune_calibration.py`: `calibrate_axis()` (Spearman ρ + percentile
|
|
19
|
+
bootstrap CI) labels an axis **outcome-validated only when the CI excludes zero**, else `weak_proxy`, and
|
|
20
|
+
`mechanistic_proxy` when N < 6. With no sufficient public paired (proxy, observed) dataset, **every axis is
|
|
21
|
+
honestly labelled a mechanistic/population proxy** — the label travels with the profile. (No fabricated
|
|
22
|
+
outcome data; machinery proven on synthetic input.)
|
|
23
|
+
- **WS-PROFILE** — `pen_stack/planner/immune_profile.py` + **`Verdict.immune_profile`**: a per-design **vector**
|
|
24
|
+
of all axes (genotoxicity, CD8 epitope, innate, pre-existing NAb, anti-PEG), each with its own value +
|
|
25
|
+
uncertainty + scope + validation label. **`collapsed_score is None`** (never fused — asserted); known-unknowns
|
|
26
|
+
listed; abstaining axes report `None`.
|
|
27
|
+
- **WS-EXT** — a documented qualitative **route/immune-privilege modifier** (eye/CNS lower realized
|
|
28
|
+
immunogenicity vs systemic; Streilein 2003 `10.1038/nri1224`; no fabricated magnitude); **CD4/MHC-II helper
|
|
29
|
+
epitopes**, **pre-existing capsid-specific T-cell immunity**, and **complement/CARPA** registered as
|
|
30
|
+
known-unknowns. `prereg/ws_{peg,calib,profile}.yaml` + SHA locks.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- Version 5.5.0 -> 5.6.0 (minor — additive); `cite.curated_dois()` ingests the anti-PEG + immune-privilege DOIs.
|
|
34
|
+
|
|
35
|
+
### Honesty invariant (unchanged)
|
|
36
|
+
- Every axis is a **relative-risk screen** (sequence/mechanistic or population proxy), labelled as such until
|
|
37
|
+
outcome-validated; the profile is **never** collapsed into one number; patient-specific titer, post-dose-1
|
|
38
|
+
induced immunity, and exact in-vivo magnitude stay **known-unknowns**.
|
|
39
|
+
|
|
6
40
|
## [5.5.0] - 2026-06-10 - v5.5 release: Anti-vector seroprevalence oracle (the last immune axis, from data)
|
|
7
41
|
|
|
8
42
|
Completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / neutralizing
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
message: "If you use PEN-STACK, please cite it as below."
|
|
3
3
|
title: "PEN-STACK: open infrastructure for genome writing"
|
|
4
|
-
version: 5.
|
|
5
|
-
date-released: 2026-06-
|
|
4
|
+
version: 5.6.0
|
|
5
|
+
date-released: 2026-06-11
|
|
6
6
|
authors:
|
|
7
7
|
- family-names: "Mahaboob Ali"
|
|
8
8
|
given-names: "Anees Ahmed"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pen-stack
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.6.0
|
|
4
4
|
Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
|
|
5
5
|
Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -87,11 +87,10 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
87
87
|
[](https://pypi.org/project/pen-stack/)
|
|
88
88
|
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
|
|
89
89
|
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml)
|
|
90
|
-
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
|
|
91
90
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
92
91
|
[](LICENSE)
|
|
93
92
|
[](https://www.python.org/)
|
|
94
|
-
[](CHANGELOG.md)
|
|
95
94
|
[](tests/)
|
|
96
95
|
[](https://github.com/astral-sh/ruff)
|
|
97
96
|
[](docker/)
|
|
@@ -135,6 +134,22 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
|
|
|
135
134
|
Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
|
|
136
135
|
a pre-registered, honest baseline before release.
|
|
137
136
|
|
|
137
|
+
## What is new in v5.6 — Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
|
|
138
|
+
|
|
139
|
+
v5.6 finishes the delivery-immunology arc and tells the truth about it. It adds the missing **anti-PEG** axis
|
|
140
|
+
(gates LNP re-dosing), **calibrates** every proxy two-sided, and exposes a **unified per-design immune-risk
|
|
141
|
+
profile** in which each axis keeps its own uncertainty and none is ever fused into one overconfident number.
|
|
142
|
+
|
|
143
|
+
| Workstream | What it adds | Result |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| **PEG** | `planner/antipeg_oracle.py` + `configs/antipeg.yaml` | anti-PEG prevalence (25–72%) → `preexisting_antipeg_score`; gates **re-dosing**; abstains for non-PEG vehicles; range surfaced as uncertainty |
|
|
146
|
+
| **CALIB** | `validate/immune_calibration.py` | each axis labelled **outcome-validated** (ρ + CI excluding 0) or **mechanistic/population proxy**; with no public paired-outcome data, all axes are honestly labelled proxies (the label travels with the profile) |
|
|
147
|
+
| **PROFILE** | `planner/immune_profile.py` + `Verdict.immune_profile` | per-design **vector** of all axes, each with value + uncertainty + scope + validation label; **`collapsed_score is None`** (never fused); known-unknowns listed |
|
|
148
|
+
| **EXT** | route/immune-privilege modifier + new known-unknowns | eye/CNS immune-privilege as a *documented qualitative* modifier (no magnitude); CD4/MHC-II, pre-existing capsid T-cell, complement/CARPA registered as known-unknowns |
|
|
149
|
+
|
|
150
|
+
The in-vivo magnitude and patient-specific titer stay declared known-unknowns. See
|
|
151
|
+
[`docs/delivery_immunology.md`](docs/delivery_immunology.md) and `prereg/ws_{peg,calib,profile}.yaml`.
|
|
152
|
+
|
|
138
153
|
## What is new in v5.5 — Anti-vector seroprevalence oracle (the last immune axis, from data)
|
|
139
154
|
|
|
140
155
|
This completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / NAb) to a
|
|
@@ -217,6 +232,11 @@ efficacious integrator but its genotoxicity is the dominant concern). Crucially,
|
|
|
217
232
|
**magnitude** stays a declared known-unknown — v5.1 surfaces documented priors, it does **not** predict a
|
|
218
233
|
patient-specific immune response.
|
|
219
234
|
|
|
235
|
+
> **The full delivery-immunology story (v5.1 → v5.5), with every axis, method, and outcome, is in
|
|
236
|
+
> [`docs/delivery_immunology.md`](docs/delivery_immunology.md).** By v5.5, four of the five immune/safety axes
|
|
237
|
+
> are computed from data or sequence (genotoxicity, adaptive/CD8, innate, pre-existing/NAb) rather than
|
|
238
|
+
> hand-typed tiers.
|
|
239
|
+
|
|
220
240
|
| Workstream | What it adds | Result |
|
|
221
241
|
|---|---|---|
|
|
222
242
|
| **IMMUNE config** | `immune_safety` block on all 8 vehicles in `configs/delivery_vehicles.yaml` | documented ordinal (low/moderate/high) priors for pre-existing immunity, neutralizing antibody, innate/adaptive immune, **genotoxicity**, efficacy — every `immune_doi` Crossref-verified and in the curated-DOI set |
|
|
@@ -381,6 +401,10 @@ benchmark with deterministic scorers and no circular labels. See
|
|
|
381
401
|
| off-target + DMS (Perry 2025) |
|
|
382
402
|
+-------------------------------------------------------------------------+
|
|
383
403
|
|
|
404
|
+
Delivery layer (v5.1-5.5, feeds the planner): a safety<->efficacy balance over the 8-vehicle palette,
|
|
405
|
+
with four of five immune/safety axes computed from data/sequence (genotoxicity = VISDB x COSMIC;
|
|
406
|
+
adaptive/CD8 = MHCflurry over the capsid; innate = CpG/dsRNA of the cargo; pre-existing/NAb = serosurveys).
|
|
407
|
+
|
|
384
408
|
Platform services (on top of the validated core): PEN-MONITOR (Europe PMC living database),
|
|
385
409
|
grounded RAG/Q&A, a tool-using agent + MCP server, and a Streamlit web app.
|
|
386
410
|
```
|
|
@@ -395,6 +419,7 @@ PEN-STACK is organised as **two reference layers + one engine + a services layer
|
|
|
395
419
|
| **Writer Atlas** (companion) | `pen_stack.atlas`, `.mech`, `.score` | cross-family enzyme catalogue + Writer-Targeting KB | Paper 2 |
|
|
396
420
|
| **Cross-link** | `pen_stack.atlas.crosslink` | bidirectional writer to locus queries | Paper 2 |
|
|
397
421
|
| **Write Planner** (engine) | `pen_stack.planner` | inverse design, `edit_intent`-conditioned | Paper 3 |
|
|
422
|
+
| **Delivery immunology** (v5.1-5.5) | `pen_stack.planner.delivery_immunology` + `{genotoxicity,capsid_epitope,seroprevalence}_oracle`, `innate_sensing` | safety↔efficacy balance over the 8-vehicle palette; 4 of 5 immune axes **computed from data/sequence**, magnitude stays a known-unknown ([docs](docs/delivery_immunology.md)) | M2 |
|
|
398
423
|
| **Agentic platform** | `pen_stack.agent` | goal to cited, auditable plan; MCP server; one-command deploy | Paper 3 |
|
|
399
424
|
| **Bridge off-target engine** | `pen_stack.bridge` | "CRISPOR for bridge recombinases" + guide QC (v3.1) | Paper 4 |
|
|
400
425
|
| **Genome-Writing Bench** (v3.1) | `benchmarks/`, `bench/run.py` | first writing-side benchmark; deterministic scorers, leaderboard | M2 |
|
|
@@ -519,12 +544,16 @@ pen-stack/
|
|
|
519
544
|
│ ├── planner/ Write Planner (Paper 3): optimize / cargo / cargo_polish / multiplex / pipeline
|
|
520
545
|
│ │ + v3.2 target_site (hard PAM/att/core reject) / delivery_constraints
|
|
521
546
|
│ │ + v3.3 router (write-type dispatch) / delivery_vehicles (8-vehicle palette)
|
|
547
|
+
│ │ + v5.1-5.5 delivery_immunology (safety<->efficacy balance) and the four
|
|
548
|
+
│ │ computed immune-axis oracles: genotoxicity_oracle (VISDB x COSMIC) /
|
|
549
|
+
│ │ capsid_epitope_oracle (MHCflurry) / innate_sensing (CpG-O/E + dsRNA) /
|
|
550
|
+
│ │ seroprevalence_oracle (anti-vector NAb serosurveys)
|
|
522
551
|
│ ├── bridge/ bridge off-target engine (Paper 4): offtarget / fold_qc / guide_qc / pipeline / cli
|
|
523
552
|
│ │ + v3.2 offtarget_energetics (position x substitution; held-out 0.88, ships)
|
|
524
553
|
│ ├── agent/ agentic platform: tools / orchestrator / pen_agent / mcp_server / guardrails; v5.0 co_scientist + cite (multi-strategy, self-critique, cited rationale, scope ledger)
|
|
525
554
|
│ │ + v3.2 epistemic (3-tier status) / scope (known-unknowns matcher)
|
|
526
555
|
│ ├── graph/ v4.5 living world-model knowledge graph (schema/build/query/ingest/cell_types); typed provenanced edges; gated living loop (propose-only)
|
|
527
|
-
│ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache
|
|
556
|
+
│ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache; v5.2-5.5 delivery-immunology scope cards (delivery_genotoxicity/capsid_epitope/innate_sensing/seroprevalence)
|
|
528
557
|
│ ├── rules/ v3.3 machine-readable rules engine (schema/evaluators/loader/solver) over configs/rules/*.yaml
|
|
529
558
|
│ ├── verify/ v3.3 verification service: verify(design) -> Verdict (legal+reasons+confidence+scope; v4.0 writer_critique)
|
|
530
559
|
│ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
|
|
@@ -540,12 +569,16 @@ pen-stack/
|
|
|
540
569
|
│ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
|
|
541
570
|
│ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
|
|
542
571
|
│ └── cli.py unified CLI
|
|
543
|
-
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.
|
|
572
|
+
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3 (T1-T16 + co_scientist; tasks / harness / solvers / LEADERBOARD / SHAs)
|
|
544
573
|
├── bench/run.py one-command bench entrypoint (--agent, --verify)
|
|
545
|
-
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, ws_*_report)
|
|
546
|
-
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2
|
|
547
|
-
│ target_sites / delivery_constraints
|
|
548
|
-
|
|
574
|
+
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
|
|
575
|
+
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
|
|
576
|
+
│ target_sites / delivery_constraints; v5.1-5.5 delivery_vehicles immune_safety /
|
|
577
|
+
│ genotoxicity_oracle / capsid_epitope_oracle + capsid_sequences.fasta /
|
|
578
|
+
│ seroprevalence + oracles/scope_cards
|
|
579
|
+
├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.5 ws_{uq,ep,mc,ba,
|
|
580
|
+
│ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
|
|
581
|
+
│ genotox,epitope,innate,seroprev} + SHA256 locks)
|
|
549
582
|
├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
|
|
550
583
|
│ v3.2 bridge_offtarget_energetics.json)
|
|
551
584
|
├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
|
|
@@ -12,11 +12,10 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
12
12
|
[](https://pypi.org/project/pen-stack/)
|
|
13
13
|
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
|
|
14
14
|
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml)
|
|
15
|
-
[](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
|
|
16
15
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
17
16
|
[](LICENSE)
|
|
18
17
|
[](https://www.python.org/)
|
|
19
|
-
[](CHANGELOG.md)
|
|
20
19
|
[](tests/)
|
|
21
20
|
[](https://github.com/astral-sh/ruff)
|
|
22
21
|
[](docker/)
|
|
@@ -60,6 +59,22 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
|
|
|
60
59
|
Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
|
|
61
60
|
a pre-registered, honest baseline before release.
|
|
62
61
|
|
|
62
|
+
## What is new in v5.6 — Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
|
|
63
|
+
|
|
64
|
+
v5.6 finishes the delivery-immunology arc and tells the truth about it. It adds the missing **anti-PEG** axis
|
|
65
|
+
(gates LNP re-dosing), **calibrates** every proxy two-sided, and exposes a **unified per-design immune-risk
|
|
66
|
+
profile** in which each axis keeps its own uncertainty and none is ever fused into one overconfident number.
|
|
67
|
+
|
|
68
|
+
| Workstream | What it adds | Result |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| **PEG** | `planner/antipeg_oracle.py` + `configs/antipeg.yaml` | anti-PEG prevalence (25–72%) → `preexisting_antipeg_score`; gates **re-dosing**; abstains for non-PEG vehicles; range surfaced as uncertainty |
|
|
71
|
+
| **CALIB** | `validate/immune_calibration.py` | each axis labelled **outcome-validated** (ρ + CI excluding 0) or **mechanistic/population proxy**; with no public paired-outcome data, all axes are honestly labelled proxies (the label travels with the profile) |
|
|
72
|
+
| **PROFILE** | `planner/immune_profile.py` + `Verdict.immune_profile` | per-design **vector** of all axes, each with value + uncertainty + scope + validation label; **`collapsed_score is None`** (never fused); known-unknowns listed |
|
|
73
|
+
| **EXT** | route/immune-privilege modifier + new known-unknowns | eye/CNS immune-privilege as a *documented qualitative* modifier (no magnitude); CD4/MHC-II, pre-existing capsid T-cell, complement/CARPA registered as known-unknowns |
|
|
74
|
+
|
|
75
|
+
The in-vivo magnitude and patient-specific titer stay declared known-unknowns. See
|
|
76
|
+
[`docs/delivery_immunology.md`](docs/delivery_immunology.md) and `prereg/ws_{peg,calib,profile}.yaml`.
|
|
77
|
+
|
|
63
78
|
## What is new in v5.5 — Anti-vector seroprevalence oracle (the last immune axis, from data)
|
|
64
79
|
|
|
65
80
|
This completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / NAb) to a
|
|
@@ -142,6 +157,11 @@ efficacious integrator but its genotoxicity is the dominant concern). Crucially,
|
|
|
142
157
|
**magnitude** stays a declared known-unknown — v5.1 surfaces documented priors, it does **not** predict a
|
|
143
158
|
patient-specific immune response.
|
|
144
159
|
|
|
160
|
+
> **The full delivery-immunology story (v5.1 → v5.5), with every axis, method, and outcome, is in
|
|
161
|
+
> [`docs/delivery_immunology.md`](docs/delivery_immunology.md).** By v5.5, four of the five immune/safety axes
|
|
162
|
+
> are computed from data or sequence (genotoxicity, adaptive/CD8, innate, pre-existing/NAb) rather than
|
|
163
|
+
> hand-typed tiers.
|
|
164
|
+
|
|
145
165
|
| Workstream | What it adds | Result |
|
|
146
166
|
|---|---|---|
|
|
147
167
|
| **IMMUNE config** | `immune_safety` block on all 8 vehicles in `configs/delivery_vehicles.yaml` | documented ordinal (low/moderate/high) priors for pre-existing immunity, neutralizing antibody, innate/adaptive immune, **genotoxicity**, efficacy — every `immune_doi` Crossref-verified and in the curated-DOI set |
|
|
@@ -306,6 +326,10 @@ benchmark with deterministic scorers and no circular labels. See
|
|
|
306
326
|
| off-target + DMS (Perry 2025) |
|
|
307
327
|
+-------------------------------------------------------------------------+
|
|
308
328
|
|
|
329
|
+
Delivery layer (v5.1-5.5, feeds the planner): a safety<->efficacy balance over the 8-vehicle palette,
|
|
330
|
+
with four of five immune/safety axes computed from data/sequence (genotoxicity = VISDB x COSMIC;
|
|
331
|
+
adaptive/CD8 = MHCflurry over the capsid; innate = CpG/dsRNA of the cargo; pre-existing/NAb = serosurveys).
|
|
332
|
+
|
|
309
333
|
Platform services (on top of the validated core): PEN-MONITOR (Europe PMC living database),
|
|
310
334
|
grounded RAG/Q&A, a tool-using agent + MCP server, and a Streamlit web app.
|
|
311
335
|
```
|
|
@@ -320,6 +344,7 @@ PEN-STACK is organised as **two reference layers + one engine + a services layer
|
|
|
320
344
|
| **Writer Atlas** (companion) | `pen_stack.atlas`, `.mech`, `.score` | cross-family enzyme catalogue + Writer-Targeting KB | Paper 2 |
|
|
321
345
|
| **Cross-link** | `pen_stack.atlas.crosslink` | bidirectional writer to locus queries | Paper 2 |
|
|
322
346
|
| **Write Planner** (engine) | `pen_stack.planner` | inverse design, `edit_intent`-conditioned | Paper 3 |
|
|
347
|
+
| **Delivery immunology** (v5.1-5.5) | `pen_stack.planner.delivery_immunology` + `{genotoxicity,capsid_epitope,seroprevalence}_oracle`, `innate_sensing` | safety↔efficacy balance over the 8-vehicle palette; 4 of 5 immune axes **computed from data/sequence**, magnitude stays a known-unknown ([docs](docs/delivery_immunology.md)) | M2 |
|
|
323
348
|
| **Agentic platform** | `pen_stack.agent` | goal to cited, auditable plan; MCP server; one-command deploy | Paper 3 |
|
|
324
349
|
| **Bridge off-target engine** | `pen_stack.bridge` | "CRISPOR for bridge recombinases" + guide QC (v3.1) | Paper 4 |
|
|
325
350
|
| **Genome-Writing Bench** (v3.1) | `benchmarks/`, `bench/run.py` | first writing-side benchmark; deterministic scorers, leaderboard | M2 |
|
|
@@ -444,12 +469,16 @@ pen-stack/
|
|
|
444
469
|
│ ├── planner/ Write Planner (Paper 3): optimize / cargo / cargo_polish / multiplex / pipeline
|
|
445
470
|
│ │ + v3.2 target_site (hard PAM/att/core reject) / delivery_constraints
|
|
446
471
|
│ │ + v3.3 router (write-type dispatch) / delivery_vehicles (8-vehicle palette)
|
|
472
|
+
│ │ + v5.1-5.5 delivery_immunology (safety<->efficacy balance) and the four
|
|
473
|
+
│ │ computed immune-axis oracles: genotoxicity_oracle (VISDB x COSMIC) /
|
|
474
|
+
│ │ capsid_epitope_oracle (MHCflurry) / innate_sensing (CpG-O/E + dsRNA) /
|
|
475
|
+
│ │ seroprevalence_oracle (anti-vector NAb serosurveys)
|
|
447
476
|
│ ├── bridge/ bridge off-target engine (Paper 4): offtarget / fold_qc / guide_qc / pipeline / cli
|
|
448
477
|
│ │ + v3.2 offtarget_energetics (position x substitution; held-out 0.88, ships)
|
|
449
478
|
│ ├── agent/ agentic platform: tools / orchestrator / pen_agent / mcp_server / guardrails; v5.0 co_scientist + cite (multi-strategy, self-critique, cited rationale, scope ledger)
|
|
450
479
|
│ │ + v3.2 epistemic (3-tier status) / scope (known-unknowns matcher)
|
|
451
480
|
│ ├── graph/ v4.5 living world-model knowledge graph (schema/build/query/ingest/cell_types); typed provenanced edges; gated living loop (propose-only)
|
|
452
|
-
│ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache
|
|
481
|
+
│ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache; v5.2-5.5 delivery-immunology scope cards (delivery_genotoxicity/capsid_epitope/innate_sensing/seroprevalence)
|
|
453
482
|
│ ├── rules/ v3.3 machine-readable rules engine (schema/evaluators/loader/solver) over configs/rules/*.yaml
|
|
454
483
|
│ ├── verify/ v3.3 verification service: verify(design) -> Verdict (legal+reasons+confidence+scope; v4.0 writer_critique)
|
|
455
484
|
│ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
|
|
@@ -465,12 +494,16 @@ pen-stack/
|
|
|
465
494
|
│ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
|
|
466
495
|
│ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
|
|
467
496
|
│ └── cli.py unified CLI
|
|
468
|
-
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.
|
|
497
|
+
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3 (T1-T16 + co_scientist; tasks / harness / solvers / LEADERBOARD / SHAs)
|
|
469
498
|
├── bench/run.py one-command bench entrypoint (--agent, --verify)
|
|
470
|
-
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, ws_*_report)
|
|
471
|
-
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2
|
|
472
|
-
│ target_sites / delivery_constraints
|
|
473
|
-
|
|
499
|
+
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
|
|
500
|
+
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
|
|
501
|
+
│ target_sites / delivery_constraints; v5.1-5.5 delivery_vehicles immune_safety /
|
|
502
|
+
│ genotoxicity_oracle / capsid_epitope_oracle + capsid_sequences.fasta /
|
|
503
|
+
│ seroprevalence + oracles/scope_cards
|
|
504
|
+
├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.5 ws_{uq,ep,mc,ba,
|
|
505
|
+
│ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
|
|
506
|
+
│ genotox,epitope,innate,seroprev} + SHA256 locks)
|
|
474
507
|
├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
|
|
475
508
|
│ v3.2 bridge_offtarget_energetics.json)
|
|
476
509
|
├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# PEN-STACK v5.6 — anti-PEG antibody prevalence (WS-PEG).
|
|
2
|
+
#
|
|
3
|
+
# Pre-existing / induced anti-PEG antibodies gate RE-DOSING of PEGylated LNP. Anti-PEG is a property of the
|
|
4
|
+
# PEGylation chemistry, NOT of any encoded sequence — so, like the v5.5 anti-vector seroprevalence, the only
|
|
5
|
+
# honest grounding is published serosurvey DATA. Curated as a population prevalence RANGE (wide assay/region
|
|
6
|
+
# variation), with serosurvey DOIs.
|
|
7
|
+
#
|
|
8
|
+
# preexisting_antipeg_score = 1 - midpoint(anti_PEG_prevalence_pct) / 100 (1 = fewest patients excluded).
|
|
9
|
+
#
|
|
10
|
+
# HONESTY (scope card `antipeg`): a POPULATION prevalence, NOT a given patient's anti-PEG titer (a clinical
|
|
11
|
+
# test, patient-specific -> a known-unknown); region/age/assay-dependent (a range, surfaced as uncertainty);
|
|
12
|
+
# applies ONLY to PEGylated vehicles (abstains otherwise). INDUCED anti-PEG after dose 1 (boosted markedly by
|
|
13
|
+
# mRNA-LNP vaccination) is a separate, larger dynamic — NOTED here, not modelled (a known-unknown).
|
|
14
|
+
|
|
15
|
+
version: "1.0"
|
|
16
|
+
|
|
17
|
+
prevalence:
|
|
18
|
+
anti_peg_prevalence_pct: [25, 72]
|
|
19
|
+
note: "pre-existing anti-PEG IgG/IgM in healthy adults; wide assay/region variation (Chen 2016 ~72% had
|
|
20
|
+
detectable anti-PEG; high-TITER prevalence is lower). Induced anti-PEG post-dose-1 is separate + larger."
|
|
21
|
+
dois:
|
|
22
|
+
- "10.1021/acs.analchem.6b03109" # Chen 2016 — pre-existing IgG/IgM anti-PEG in healthy individuals
|
|
23
|
+
- "10.1002/wnan.1339" # Yang & Lai 2015 — anti-PEG immunity review
|
|
24
|
+
- "10.1002/cncr.22739" # Armstrong 2007 — anti-PEG antibodies adversely affect PEG-asparaginase
|
|
25
|
+
- "10.1016/j.addr.2020.07.024" # Kozma 2020 — anti-PEG antibodies (properties/formation/testing)
|
|
26
|
+
|
|
27
|
+
# which palette vehicles are PEGylated (LNP-mRNA uses a PEG-lipid). All others abstain.
|
|
28
|
+
pegylated_vehicles: [lnp_mrna]
|
|
@@ -65,3 +65,30 @@ known_unknowns:
|
|
|
65
65
|
match_terms: ["germline", "heritable", "pass to offspring", "embryo", "inherited by children",
|
|
66
66
|
"future generations"]
|
|
67
67
|
patterns: []
|
|
68
|
+
|
|
69
|
+
# v5.6 WS-EXT — immune axes that are mechanistically distinct from what the v5.2-v5.6 oracles compute, and
|
|
70
|
+
# for which PEN-STACK has no grounded model: declared known-unknowns rather than faked.
|
|
71
|
+
- id: cd4_mhcii_help
|
|
72
|
+
title: "CD4 / MHC-II helper-epitope load"
|
|
73
|
+
requires: "MHC-II binding prediction over the capsid/transgene + a model linking CD4 help to antibody/memory formation"
|
|
74
|
+
why: "the v5.3 capsid-epitope oracle computes CD8 / MHC-I presentation ONLY; CD4 / MHC-II helper epitopes
|
|
75
|
+
(which drive antibody formation and durable memory) are NOT modelled — a distinct, ungrounded axis here"
|
|
76
|
+
match_terms: ["cd4", "mhc-ii", "mhc class ii", "helper t", "helper epitope", "th cell", "t-helper"]
|
|
77
|
+
patterns: []
|
|
78
|
+
|
|
79
|
+
- id: preexisting_capsid_tcell
|
|
80
|
+
title: "pre-existing capsid-specific memory T-cell immunity"
|
|
81
|
+
requires: "population prevalence of capsid-specific memory T cells (distinct from neutralizing-antibody serosurveys)"
|
|
82
|
+
why: "v5.5 seroprevalence is anti-vector ANTIBODY (B-cell) prevalence; pre-existing capsid-specific
|
|
83
|
+
memory T-CELL immunity is a separate dimension PEN-STACK does NOT model (sparse, assay-dependent data)"
|
|
84
|
+
match_terms: ["pre-existing t-cell", "preexisting t cell", "capsid-specific t cell", "memory t cell",
|
|
85
|
+
"t-cell immunity to capsid", "cellular pre-existing immunity"]
|
|
86
|
+
patterns: []
|
|
87
|
+
|
|
88
|
+
- id: complement_carpa
|
|
89
|
+
title: "complement activation / CARPA (complement-activation-related pseudoallergy)"
|
|
90
|
+
requires: "a model of complement activation by the vector/LNP surface (C3/C5 turnover, anaphylatoxins) and infusion-reaction risk"
|
|
91
|
+
why: "complement/CARPA is mechanistically distinct from the cargo CpG/dsRNA innate axis (v5.4) and the
|
|
92
|
+
capsid epitope axis; PEN-STACK does NOT model complement activation or infusion-reaction risk"
|
|
93
|
+
match_terms: ["complement", "carpa", "c3a", "c5a", "anaphylatox", "infusion reaction", "pseudoallergy"]
|
|
94
|
+
patterns: []
|
|
@@ -166,3 +166,16 @@ oracles:
|
|
|
166
166
|
generalizes_to_unseen_loci: false
|
|
167
167
|
license: "open (this work; Calcedo 10.1086/595830, Boutin 10.1089/hum.2009.182, Mast
|
|
168
168
|
10.1016/j.vaccine.2009.10.145, Looker 10.1371/journal.pone.0140765)"
|
|
169
|
+
|
|
170
|
+
antipeg: # v5.6 WS-PEG: anti-PEG antibody prevalence (gates LNP re-dosing)
|
|
171
|
+
family: genome
|
|
172
|
+
version: "serosurvey-2026"
|
|
173
|
+
output_kind: baseline # curated empirical population data, not a model
|
|
174
|
+
valid_for: "POPULATION pre-existing anti-PEG antibody prevalence for PEGylated LNP (a property of the PEG
|
|
175
|
+
chemistry, not an encoded sequence); preexisting_antipeg_score = 1 - midpoint/100; gates RE-DOSING"
|
|
176
|
+
not_valid_for: "a given PATIENT's anti-PEG titer / sero-status (a clinical test, patient-specific -> a
|
|
177
|
+
known-unknown); INDUCED anti-PEG after dose 1 (a separate, larger dynamic, esp. post mRNA-LNP); precise
|
|
178
|
+
region/age/assay values (a range, not a point); non-PEGylated vehicles (abstains)"
|
|
179
|
+
generalizes_to_unseen_loci: false
|
|
180
|
+
license: "open (this work; Chen 10.1021/acs.analchem.6b03109, Yang&Lai 10.1002/wnan.1339,
|
|
181
|
+
Armstrong 10.1002/cncr.22739, Kozma 10.1016/j.addr.2020.07.024)"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Delivery immunology — the safety↔efficacy balance (v5.1 → v5.5)
|
|
2
|
+
|
|
3
|
+
PEN-STACK scores and constrains the **whole** delivery palette (8 vehicles), not just dual-AAV. v5.1–v5.5 added
|
|
4
|
+
a delivery **safety↔efficacy** layer: a per-vehicle immune / safety / efficacy profile, a user-weightable
|
|
5
|
+
ranking, and — crucially — **four of the five immune/safety axes are now grounded in real data or sequence**
|
|
6
|
+
rather than hand-typed `low/moderate/high` tiers.
|
|
7
|
+
|
|
8
|
+
> **The honesty invariant (unchanged across the program).** The in-vivo immune *magnitude* — how strongly a
|
|
9
|
+
> given patient or construct will actually react — is a declared **known-unknown**
|
|
10
|
+
> (`configs/known_unknowns.yaml: in_vivo_immunogenicity`) and is **never predicted**. Every oracle below
|
|
11
|
+
> abstains rather than fabricate when it lacks data, and each carries a scope card stating exactly what it is
|
|
12
|
+
> *not* valid for. What is surfaced is a relative, auditable, cited signal — not a per-patient prediction.
|
|
13
|
+
|
|
14
|
+
## The 8-vehicle palette
|
|
15
|
+
|
|
16
|
+
`configs/delivery_vehicles.yaml` — AAV (single / dual), lentivirus, helper-dependent adenovirus, HSV amplicon,
|
|
17
|
+
LNP-mRNA, eVLP, electroporation. Each carries cargo capacity, integration, cargo form, an `immune_safety` block
|
|
18
|
+
(documented ordinal priors + cited DOIs), and the computed-oracle hooks below.
|
|
19
|
+
|
|
20
|
+
## The safety↔efficacy profile
|
|
21
|
+
|
|
22
|
+
`pen_stack/planner/delivery_immunology.py::safety_efficacy_profile(vehicle)` returns, per vehicle:
|
|
23
|
+
|
|
24
|
+
- **two separate safety sub-axes** — never collapsed, because they are different *kinds* of risk:
|
|
25
|
+
- `immune_score` — immunogenicity (largely reversible; bears on eligibility / re-dosing), the mean of four
|
|
26
|
+
immune axes (pre-existing, NAb, innate, adaptive);
|
|
27
|
+
- `genotox_score` — insertional / oncogenic risk (permanent);
|
|
28
|
+
- a headline `safety_score = min(immune_score, genotox_score)` (precautionary worst-axis);
|
|
29
|
+
- `efficacy_score`, the documented `tradeoff` sentence, and the standing magnitude scope flag.
|
|
30
|
+
|
|
31
|
+
`recommend_delivery(cargo_form, cargo_bp, safety_weight, in_vivo)` ranks the eligible palette along the
|
|
32
|
+
frontier: `balance = safety_weight·safety + (1−safety_weight)·efficacy`. Move `safety_weight` from 0→1 to slide
|
|
33
|
+
from efficacy-first to safety-first. This reproduces the motivating tradeoff: **AAV** is dinged on
|
|
34
|
+
immunogenicity (non-integrating, but NAb-limited), **lentivirus** on genotoxicity (a highly efficacious
|
|
35
|
+
integrator whose insertional risk is the dominant concern).
|
|
36
|
+
|
|
37
|
+
`verify(design)` surfaces the profile as `delivery_profile` plus a `delivery_immune_profile` scope flag, and —
|
|
38
|
+
when a `cargo_seq` is supplied — a `cargo_innate_sensing` flag (see below).
|
|
39
|
+
|
|
40
|
+
## v5.6 — completion & calibration: anti-PEG, proxy honesty, and the unified profile
|
|
41
|
+
|
|
42
|
+
v5.6 finishes the picture and tells the truth about it (`docs` + `pen_stack/planner/{antipeg_oracle,immune_profile}.py`,
|
|
43
|
+
`pen_stack/validate/immune_calibration.py`):
|
|
44
|
+
|
|
45
|
+
- **Anti-PEG axis (WS-PEG)** — `antipeg_oracle.py` + `configs/antipeg.yaml`. Pre-existing/induced anti-PEG
|
|
46
|
+
antibodies gate **re-dosing** of PEGylated LNP. Same honest serosurvey pattern as v5.5: a population
|
|
47
|
+
prevalence **range** (25–72 %, Chen 2016 / Yang & Lai 2015 / Armstrong 2007 / Kozma 2020) →
|
|
48
|
+
`preexisting_antipeg_score = 1 − midpoint/100 = 0.515`, range surfaced as uncertainty. **Abstains** for
|
|
49
|
+
non-PEGylated vehicles. Patient titer and post-dose-1 *induced* anti-PEG stay known-unknowns.
|
|
50
|
+
- **Proxy calibration (WS-CALIB)** — `immune_calibration.py`. `calibrate_axis()` computes a Spearman ρ +
|
|
51
|
+
bootstrap CI and labels an axis **outcome-validated only when the CI excludes zero** (else `weak_proxy`;
|
|
52
|
+
`mechanistic_proxy` when N < 6). Because no sufficient public *paired* (proxy, observed-immunogenicity)
|
|
53
|
+
dataset exists, **every axis is currently labelled a mechanistic/population proxy** — that honest label is
|
|
54
|
+
the deliverable, and it travels with the profile. (The machinery is proven on synthetic data; it will
|
|
55
|
+
promote an axis only from real data.)
|
|
56
|
+
- **Unified immune-risk profile (WS-PROFILE)** — `immune_profile.py`, exposed as **`Verdict.immune_profile`**.
|
|
57
|
+
A per-design **vector** of all axes, each with its own value + uncertainty + scope + validation label;
|
|
58
|
+
**`collapsed_score is None`** (never fused into one overconfident number — asserted by test);
|
|
59
|
+
`known_unknowns` listed; abstaining axes report `None`, not a guess.
|
|
60
|
+
- **WS-EXT** — a documented qualitative **route/immune-privilege modifier** (eye/CNS materially lower realized
|
|
61
|
+
immunogenicity vs systemic; Streilein 2003 `10.1038/nri1224`; *no* fabricated magnitude), and three
|
|
62
|
+
mechanistically-distinct axes registered as **known-unknowns**: CD4/MHC-II helper epitopes,
|
|
63
|
+
pre-existing capsid-specific T-cell immunity, and complement/CARPA.
|
|
64
|
+
|
|
65
|
+
## The axes — four computed/grounded, anti-PEG added, one documented
|
|
66
|
+
|
|
67
|
+
| Axis | Risk kind | v5.1 | Now | Grounding |
|
|
68
|
+
|---|---|---|---|---|
|
|
69
|
+
| **Genotoxicity** | permanent / oncogenic | tier | **computed** (v5.2) | integration-site catalogues × oncogene loci |
|
|
70
|
+
| **Adaptive (CD8 T-cell)** | reversible | tier | **computed** (v5.3) | MHC-I epitope load over the capsid sequence |
|
|
71
|
+
| **Innate** | reversible | tier | **computed** (v5.4) | CpG / dsRNA motif load of the cargo sequence |
|
|
72
|
+
| **Pre-existing / NAb (B-cell)** | reversible (eligibility) | tier | **data-grounded** (v5.5) | published serosurveys |
|
|
73
|
+
| **Anti-PEG (LNP re-dosing)** | reversible (re-dosing) | — | **data-grounded** (v5.6) | anti-PEG serosurveys |
|
|
74
|
+
| **Efficacy** | — | tier | documented | construct/context-specific by nature |
|
|
75
|
+
|
|
76
|
+
Each computed signal answers through the v4.0 `OracleResult` contract (value + provenance + native uncertainty
|
|
77
|
+
+ scope card + `output_kind="baseline"`), and the small committed artifacts (where any) keep the heavy
|
|
78
|
+
data/models on the VM so the package and CI stay light.
|
|
79
|
+
|
|
80
|
+
### Genotoxicity — `genotoxicity_oracle.py` (v5.2, WS-GENOTOX)
|
|
81
|
+
|
|
82
|
+
For an **integrating** vector, the observed enrichment of its integration sites near COSMIC Cancer-Gene-Census
|
|
83
|
+
oncogenes: `P(site within 50 kb of an oncogene)` over the vector class's VISDB catalogue, vs genome background
|
|
84
|
+
(2.21 %). `genotox_score = min(1, 1/enrichment)`.
|
|
85
|
+
|
|
86
|
+
- **Lentiviral (HIV) 2.08×** enrichment (n = 88,743, robust) vs **gammaretroviral (MLV) 5.65×** (the LMO2 /
|
|
87
|
+
SCID-X1 comparator; n = 32, flagged small-n) — reproducing the *lentivirus-safer-than-gammaretrovirus*
|
|
88
|
+
ordering **from data**. The computed lentivirus score (0.48) **validates** the v5.1 documented "moderate"
|
|
89
|
+
tier (0.5).
|
|
90
|
+
- Non-integrating vehicles → 1.0 by mechanism. *Not valid for:* the in-vivo clonal / leukemogenesis **outcome**
|
|
91
|
+
(a known-unknown). Build: `scripts/p52_build_genotox_oracle.py` → `configs/genotoxicity_oracle.yaml`.
|
|
92
|
+
Provenance: VISDB `10.1093/nar/gkz867`, COSMIC CGC `10.1038/s41568-018-0060-1`.
|
|
93
|
+
|
|
94
|
+
### Adaptive / CD8 — `capsid_epitope_oracle.py` (v5.3, WS-EPITOPE)
|
|
95
|
+
|
|
96
|
+
For a **viral** vector, the fraction of its capsid/envelope antigen presentable to CD8 T cells across a
|
|
97
|
+
frequent HLA-I panel (MHCflurry 2.0, %rank ≤ 0.5 over 9-mers × 12 alleles): `capsid_immune_score = 1 −
|
|
98
|
+
epitope_fraction_strong`.
|
|
99
|
+
|
|
100
|
+
- AAV2 VP1 is the **least** epitope-dense capsid (0.72), Ad5 hexon among the most (0.82) — the documented
|
|
101
|
+
adaptive ordering reproduced **from sequence**. All 8 vehicles covered (5 viral computed, 3 non-viral 1.0 by
|
|
102
|
+
mechanism).
|
|
103
|
+
- The score is *intrinsic* presentability, so it is folded into the adaptive axis **only for in-vivo**
|
|
104
|
+
vehicles; for **ex-vivo lentivirus** (VSV-G is intrinsically epitope-dense but barely seen ex vivo) it is
|
|
105
|
+
reported but muted. *Not valid for:* the patient-HLA-specific response (a known-unknown); antibody immunity
|
|
106
|
+
(this is CD8/MHC-I only). Sequences UniProt-verified (`configs/capsid_sequences.fasta`: AAV2 VP1 P03135, Ad5
|
|
107
|
+
hexon P04133, VSV-G P03522, HSV-1 gD P57083 + gB P06437). Provenance: MHCflurry `10.1016/j.cels.2020.06.010`,
|
|
108
|
+
HLA supertypes `10.1186/1471-2172-9-1`.
|
|
109
|
+
|
|
110
|
+
### Innate — `innate_sensing.py` (v5.4, WS-INNATE)
|
|
111
|
+
|
|
112
|
+
For the **cargo sequence** (computed live in `verify()` when a `cargo_seq` is supplied):
|
|
113
|
+
|
|
114
|
+
- **DNA** → CpG observed/expected (TLR9/cGAS): vertebrate genome ~0.2 is tolerated, non-depleted DNA → 1 is
|
|
115
|
+
stimulatory; `innate_score = max(0, 1 − CpG_O/E)`.
|
|
116
|
+
- **mRNA** → U-richness + ViennaRNA dsRNA pairing (TLR7/8 + RIG-I/MDA5/PKR); a **partial** signal (flagged
|
|
117
|
+
`extrapolating`) — the dominant evasion lever, nucleoside modification (m1-pseudouridine), is *not*
|
|
118
|
+
sequence-derivable.
|
|
119
|
+
- **RNP** → minimal/transient. *Not valid for:* the realized in-vivo innate response, RNA nucleoside
|
|
120
|
+
modification, DNA methylation state. Provenance: CpG-TLR9 `10.1073/pnas.161293498`, CpG-depleted AAV
|
|
121
|
+
`10.1172/JCI68205`, RNA modification `10.1016/j.immuni.2005.06.008`.
|
|
122
|
+
|
|
123
|
+
### Pre-existing / neutralizing antibody — `seroprevalence_oracle.py` (v5.5, WS-SEROPREV)
|
|
124
|
+
|
|
125
|
+
The one axis that **cannot** be computed from sequence — anti-capsid NAb seroprevalence is a population
|
|
126
|
+
prevalence from natural exposure. Grounded in published serosurveys (`configs/seroprevalence.yaml`, ranges with
|
|
127
|
+
DOIs): `preexisting_score = 1 − midpoint(seroprevalence)/100`, range half-width surfaced as native uncertainty.
|
|
128
|
+
|
|
129
|
+
| Serotype (vehicle) | NAb seroprevalence | pre-existing score |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| Ad5 → HDAd | 40–90 % | 0.35 |
|
|
132
|
+
| HSV-1 → HSV | 50–70 % | 0.40 |
|
|
133
|
+
| AAV (aggregate) → AAV | 30–60 % | 0.55 |
|
|
134
|
+
| VSV → lentivirus | 0–5 % | 0.975 (muted, ex-vivo) |
|
|
135
|
+
|
|
136
|
+
Folded for in-vivo vehicles (serum NAb neutralises the vector in vivo), muted for ex-vivo; non-viral → 1.0 by
|
|
137
|
+
mechanism. *Not valid for:* a given **patient's** NAb titer / sero-status (a clinical test, patient-specific →
|
|
138
|
+
a known-unknown). Provenance: Calcedo `10.1086/595830`, Boutin `10.1089/hum.2009.182`, Mast
|
|
139
|
+
`10.1016/j.vaccine.2009.10.145`, Looker `10.1371/journal.pone.0140765`.
|
|
140
|
+
|
|
141
|
+
## Outcome
|
|
142
|
+
|
|
143
|
+
Across v5.1→v5.5 the delivery immune/safety profile moved from documented `low/moderate/high` tiers to **real
|
|
144
|
+
calculations from data and sequence** on four of the five axes, spanning all 8 vehicles — each grounded, each
|
|
145
|
+
abstaining rather than fabricating, with the in-vivo magnitude always a declared known-unknown. The result is
|
|
146
|
+
the safety↔efficacy balance the program set out to provide: *computed wherever the science allows, documented
|
|
147
|
+
where it does not, and explicitly out-of-scope where no one can yet predict.*
|
|
148
|
+
|
|
149
|
+
See also: [Oracle mesh](oracles.md) · [Delivery palette & router](delivery.md) · [Verification](verify.md) ·
|
|
150
|
+
[Scope & known-unknowns](scope.md). Pre-registrations: `prereg/ws_{immune,genotox,epitope,innate,seroprev}.yaml`.
|
|
@@ -12,6 +12,7 @@ Three layers, one engine:
|
|
|
12
12
|
| **Writer Atlas** (`pen_stack.atlas` / `mech` / `score`) | What can write, and how well? (33,370 systems across 8 families, measured axes) |
|
|
13
13
|
| **Cross-link** (`pen_stack.atlas.crosslink`) | Which writers reach a locus / which loci a writer reaches |
|
|
14
14
|
| **Write Planner** (`pen_stack.planner`, Phase 3) | Find the optimal site x writer x cargo x delivery for a goal |
|
|
15
|
+
| **Delivery immunology** (`pen_stack.planner.delivery_immunology` + oracles) | Balance safety vs efficacy across the 8-vehicle palette — four of five immune/safety axes **computed from data/sequence** ([details](delivery_immunology.md)) |
|
|
15
16
|
|
|
16
17
|
## Install
|
|
17
18
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""PEN-STACK v3.0 - open infrastructure for genome writing."""
|
|
2
|
-
__version__ = "5.
|
|
2
|
+
__version__ = "5.6.0"
|
|
@@ -46,6 +46,15 @@ def curated_dois() -> frozenset[str]:
|
|
|
46
46
|
dois.update(_rec.get("dois", []) or [])
|
|
47
47
|
except FileNotFoundError:
|
|
48
48
|
pass
|
|
49
|
+
# v5.6 anti-PEG serosurvey provenance
|
|
50
|
+
try:
|
|
51
|
+
ap = yaml.safe_load(resource("configs/antipeg.yaml").read_text(encoding="utf-8"))
|
|
52
|
+
dois.update((ap.get("prevalence") or {}).get("dois", []) or [])
|
|
53
|
+
except FileNotFoundError:
|
|
54
|
+
pass
|
|
55
|
+
# v5.6 WS-EXT route/immune-privilege modifier provenance
|
|
56
|
+
from pen_stack.planner.immune_profile import ROUTE_MODIFIER_DOI
|
|
57
|
+
dois.add(ROUTE_MODIFIER_DOI)
|
|
49
58
|
gsh = yaml.safe_load(resource("configs/gsh_validated_heldout.yaml").read_text(encoding="utf-8"))["gsh"]
|
|
50
59
|
for g in gsh:
|
|
51
60
|
if g.get("doi"):
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Anti-PEG immunity axis for PEGylated LNP (v5.6, WS-PEG).
|
|
2
|
+
|
|
3
|
+
The one delivery-immunology axis missing from v5.1-v5.5: pre-existing / induced anti-PEG antibodies, which
|
|
4
|
+
gate RE-DOSING of PEGylated LNP. Anti-PEG is a property of the PEGylation chemistry, not of any encoded
|
|
5
|
+
sequence — so, exactly like the v5.5 anti-vector seroprevalence oracle, it is grounded in published serosurvey
|
|
6
|
+
DATA (configs/antipeg.yaml, a population prevalence range with DOIs):
|
|
7
|
+
|
|
8
|
+
preexisting_antipeg_score = 1 - midpoint(anti_PEG_prevalence_pct) / 100 # 1 = fewest excluded
|
|
9
|
+
|
|
10
|
+
Answers through the v4.0 OracleResult contract (output_kind="baseline"). ABSTAINS for non-PEGylated vehicles.
|
|
11
|
+
HONESTY: a POPULATION prevalence (a range, region/age/assay-dependent), NOT a given patient's anti-PEG titer
|
|
12
|
+
(a clinical test, patient-specific -> a known-unknown); induced anti-PEG after dose 1 is a separate, larger
|
|
13
|
+
dynamic (noted, not modelled).
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from functools import lru_cache
|
|
18
|
+
|
|
19
|
+
import yaml
|
|
20
|
+
|
|
21
|
+
from pen_stack._resources import resource
|
|
22
|
+
from pen_stack.oracles.schema import OracleResult, Provenance
|
|
23
|
+
|
|
24
|
+
_SCOPE_CARD = "antipeg"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@lru_cache(maxsize=1)
|
|
28
|
+
def _table() -> dict:
|
|
29
|
+
return yaml.safe_load(resource("configs/antipeg.yaml").read_text(encoding="utf-8"))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _all_dois() -> list[str]:
|
|
33
|
+
return list((_table().get("prevalence") or {}).get("dois", []) or [])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _prov(**extra) -> Provenance:
|
|
37
|
+
return Provenance(model="anti_peg_seroprevalence", version=str(_table().get("version", "1.0")),
|
|
38
|
+
source="cache", extra=extra)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def antipeg_oracle(vehicle_name: str, pegylated: bool | None = None) -> OracleResult:
|
|
42
|
+
"""Anti-PEG pre-existing immunity for a vehicle, as an OracleResult (v4.0 contract).
|
|
43
|
+
|
|
44
|
+
- PEGylated vehicle -> preexisting_antipeg_score = 1 - midpoint(prevalence)/100 (gates RE-DOSING).
|
|
45
|
+
- non-PEGylated vehicle -> ABSTAINS (available=False, value=None): the anti-PEG axis is not applicable.
|
|
46
|
+
`pegylated` overrides the config's vehicle list when given. Never fabricates a patient titer."""
|
|
47
|
+
t = _table()
|
|
48
|
+
is_peg = pegylated if pegylated is not None else (vehicle_name in (t.get("pegylated_vehicles") or []))
|
|
49
|
+
if not is_peg:
|
|
50
|
+
return OracleResult(oracle="genome", value=None, provenance=_prov(), scope_card=_SCOPE_CARD,
|
|
51
|
+
in_scope=False, available=False, output_kind="baseline",
|
|
52
|
+
note=f"non-PEGylated vehicle {vehicle_name!r}: anti-PEG axis not applicable (abstains).")
|
|
53
|
+
|
|
54
|
+
rec = t["prevalence"]
|
|
55
|
+
lo, hi = rec["anti_peg_prevalence_pct"]
|
|
56
|
+
mid = (lo + hi) / 2.0
|
|
57
|
+
score = max(0.0, min(1.0, 1.0 - mid / 100.0))
|
|
58
|
+
return OracleResult(
|
|
59
|
+
oracle="genome",
|
|
60
|
+
value={"preexisting_antipeg_score": round(score, 3), "anti_peg_prevalence_pct": [lo, hi],
|
|
61
|
+
"midpoint_pct": mid, "gates": "re-dosing", "dois": rec.get("dois", [])},
|
|
62
|
+
provenance=_prov(dois=rec.get("dois", [])), native_uncertainty=round((hi - lo) / 200.0, 4),
|
|
63
|
+
scope_card=_SCOPE_CARD, in_scope=True, extrapolating=False, output_kind="baseline", available=True,
|
|
64
|
+
note=(f"population anti-PEG prevalence {lo}-{hi}% -> preexisting_antipeg_score={score:.3f}; gates "
|
|
65
|
+
"RE-DOSING of PEGylated LNP. A POPULATION range (region/age/assay-dependent) - NOT a patient's "
|
|
66
|
+
"anti-PEG titer (a known-unknown); induced anti-PEG after dose 1 is a separate, larger dynamic "
|
|
67
|
+
"(not modelled)."))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def computed_antipeg_score(vehicle_name: str, pegylated: bool | None = None) -> tuple[float | None, OracleResult]:
|
|
71
|
+
"""Convenience: (anti-PEG score or None, full OracleResult). None when the oracle abstains (non-PEG).
|
|
72
|
+
Never fabricates."""
|
|
73
|
+
r = antipeg_oracle(vehicle_name, pegylated)
|
|
74
|
+
val = (r.value or {}).get("preexisting_antipeg_score") if (r.available and r.value) else None
|
|
75
|
+
return val, r
|