pen-stack 7.1.8__tar.gz → 7.2.1__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-7.1.8 → pen_stack-7.2.1}/CHANGELOG.md +96 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/CITATION.cff +2 -2
- {pen_stack-7.1.8 → pen_stack-7.2.1}/MANIFEST.in +1 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/PKG-INFO +1 -1
- pen_stack-7.2.1/benchmarks/offtarget/integrase/README.md +23 -0
- pen_stack-7.2.1/benchmarks/offtarget/integrase/SHA256SUMS +4 -0
- pen_stack-7.2.1/data/curated/cast_systems.yaml +59 -0
- pen_stack-7.2.1/data/curated/integrase_att.yaml +66 -0
- pen_stack-7.2.1/data/offtarget/enumerated_cache.parquet +0 -0
- pen_stack-7.2.1/data/offtarget/motif_cache.parquet +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/offtarget_data.md +25 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/__init__.py +1 -1
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/mcp_server.py +9 -6
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/api/manifest.py +7 -5
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/server/api.py +23 -5
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/offtarget_assay.py +24 -1
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_bridge.py +47 -0
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_cast.py +97 -0
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_enumerate.py +271 -0
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_integrase.py +111 -0
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_nuclease.py +66 -0
- pen_stack-7.2.1/pen_stack/wgenome/offtarget_paste.py +41 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/offtarget_predict.py +35 -14
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/PKG-INFO +1 -1
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/SOURCES.txt +14 -0
- pen_stack-7.2.1/prereg/SHA256_LOCK_ws_offtarget2.json +9 -0
- pen_stack-7.2.1/prereg/ws_offtarget2.yaml +106 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pyproject.toml +1 -1
- {pen_stack-7.1.8 → pen_stack-7.2.1}/LICENSE +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/bench/run.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_grounding/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_grounding/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_headtohead/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_routing/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_routing/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_safety/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/chat_safety/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/delivery/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_challenge/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/loop/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/offtarget/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/oracle/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/position_effect/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/position_effect/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/verify/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/writer_efficiency/README.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/benchmarks/writespec/SHA256SUMS +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/aav_serotype_tropism.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/antipeg.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/atlas_families.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/calibration/preexisting_nab_independent.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/cargo_polish.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/cell_types.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/datasets.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/delivery_rules.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/expression/modifiers.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/expression/promoters.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/gates_v3.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/genotoxicity_oracle.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/intent_weights.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/known_unknowns.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/llm.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/metric_guide.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/mhc_epitope_oracle.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/monitor_queries.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/oracles/execution.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/oracles/reliability.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/oracles/scope_cards.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/compliance.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/delivery.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/fold.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/payload.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/rules/reachability.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/safety/hazard_registry.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/safety/policy.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/safety/probes.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/score_axes.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/seroprevalence.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/target_sites.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/write_types.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/writer_sequences.fasta +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/BACKLOG.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/DEPLOY.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/INFRA.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/MCP.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/RELEASING.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/REPRO.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/STABILITY.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/agent.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/autonomy.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/benchmark_circularity.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/biosecurity.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/build_interface.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/atlas.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/durability.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/position_effect_data.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/safety.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/cards/writer_efficiency_data.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/challenge.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/closed_loop.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/co_scientist.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/co_scientist_loop.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/delivery.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/delivery_immunology.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/delivery_recommender.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/digital_twin.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/dissemination.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/environment.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/experiment_design.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/generative_design.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/immune_profiler.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/index.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/integrations.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/live_oracles.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/offtarget.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/oracle_mesh.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/oracles.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/position_effect.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/positioning.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/private_data_formats.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/quickstart.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/responsible_use.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/rule_spec.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/rules.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/scope.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/scorecard.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/tpe_bench.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/uncertainty.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/verify.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/verify_service.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/world_model.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/writer_efficiency.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/writer_verification.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/writespec_bench.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/writespec_profile.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/docs/wtkb.md +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/_resources.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/acquire.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/brains.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/campaign.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/design.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/active/validate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/adapt/report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/cite.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/epistemic.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/orchestrator.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/orchestrator_live.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/scope.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/agent/tools.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/api/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/crosslink.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/guide_design.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/writer_efficiency.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/writer_predict.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/writer_recommend.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/build/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/build/cloudlab.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/build/ingest.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/build/protocol.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/build/simlab.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/cli.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/encode.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/genome.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/ingest_safety_annot.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/capsid_generate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/generate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/pareto.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/space.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/design/writer_variants.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/env/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/env/policies.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/build.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/query.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/graph/schema.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/loop/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/loop/continual.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/loop/cycle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/loop/drift.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/monitor/run.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/affinity.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/reliability.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/schema.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/status.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/structure.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/structure_run.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/oracles/vcell.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/ada_risk.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/antipeg_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/chromosome.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery_immune.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery_predict.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/genotoxicity_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/immune_mhc2.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/immune_profile.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/optimize.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/pipeline.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/router.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/corpus.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/embed.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/ground.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/index.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/llm.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/qa.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rag/retrieve.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/evaluators.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/loader.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/schema.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/solver.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/rules/spec.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/audit.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/gate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/policy.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/redteam.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/registry.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/screen.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/safety/standards.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/score/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/server/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/clarify.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/extract.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/cell.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/chem.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/feature.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/gene.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/locus.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/resolvers/phenotype.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/satisfy.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/service.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/spec/writespec.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/calibrate.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/data/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/data/position_effect.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/mechanistic.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/outcome.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/twin/position_effect.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/ui/app.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/closed_loop.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/experiment_design.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/expr_controls.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/generative_design.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/heldout_celltype_expr.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/immune_calibration.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/known_biology_expr.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/outcome_prediction.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/paper3_benchmark.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/protocol_safety.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/safety_screening.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/verify/proof.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/verify/schema.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/verify/service.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/guide.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/llm.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/llm_provider.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/router.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/server.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/web/tools.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/offtarget_data.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/requires.txt +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_acq.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_calib.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_chat.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_closedloop.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_continual.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_drift.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_gen.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_loop.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_mech.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_oracle.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_orch.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_peg.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_penchat.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_policy.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_profile.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_proto.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_screen.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_verify.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_writer.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_writespec.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/paper1.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/paper2.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/paper3.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/paper4.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/phase0.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_a.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_acq.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_aldesign.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_alvalidate.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_b.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ba.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_bench.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_c.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_cal.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_calib.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_challenge.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_chat.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_cite.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_closedloop.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_continual.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_cosci2.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_crit.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ct.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_d.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_delivery.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_drift.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_e.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_env.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ep.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_expr2.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_f.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_frontend.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_g.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_gen.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_graph.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_h.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_hybrid.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_immune.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_immune2.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_ingest.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_innate.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_loop.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_manifest.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_mc.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_mcp.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_mech.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_mon.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_o.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_offtarget.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_openapi.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_oracle.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_orch.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_outcome.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_pareto.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_peg.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_penchat.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_plan.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_policy.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_profile.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_proto.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_r.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_redteam.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_route.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_screen.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_simlab.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_twincal.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_uq.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_v.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_vcell.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_verify.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_writer.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_writespec.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/prereg/ws_wv.yaml +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/build_capsid_fitness.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/build_rag_corpus.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/calibrate_immune_axes.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/fetch_licensed_sources.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/offtarget_chromatin_incremental.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/offtarget_chromatin_matched.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/offtarget_chromatin_validation.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_build_durability.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_build_position_effect.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_build_writer_eff.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_train_safety.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p1_validation_report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p52_build_genotox_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/ws_b_report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/scripts/ws_c_report.py +0 -0
- {pen_stack-7.1.8 → pen_stack-7.2.1}/setup.cfg +0 -0
|
@@ -3,6 +3,102 @@
|
|
|
3
3
|
All notable changes to PEN-STACK are documented here. This file follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
|
|
6
|
+
## [7.2.1] - 2026-07-02 - PhiC31 integrase: close the O-WS3/O-G2 data gap with verified data + a sealed recall benchmark (honest NEGATIVE)
|
|
7
|
+
|
|
8
|
+
Closes the one genuine open item from v7.2.0 — the PhiC31 integrase data gap — with independently-verified,
|
|
9
|
+
open, citable sequences (no fabrication) and a **sealed recall benchmark whose result is reported verbatim**.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **PhiC31 is now encoded** (`data/curated/integrase_att.yaml`), replacing the v7.2.0 abstain-with-disclosure. All
|
|
13
|
+
data was **independently validated against NCBI/RCSB** (which caught two errors in the completion pack's
|
|
14
|
+
citations, since corrected): att from **PDB 9U2T/9U2S** ("PhiC31 integrase-attB-attP synaptic complex"; the
|
|
15
|
+
canonical Groth-2000 34 bp attB is present in attB53); the documented human pseudo-attP **ψA/ψC/ψD** from
|
|
16
|
+
**GenBank AF333429/AF333430/AF333431** (Thyagarajan 2001, *Mol Cell Biol* 21(12), PMID 11359900,
|
|
17
|
+
DOI `10.1128/MCB.21.12.3926-3934.2001`; chr8/16/15). Corrected DOIs: Groth 2000 `10.1073/pnas.090527097`,
|
|
18
|
+
Chalberg 2006 `10.1016/j.jmb.2005.11.098` (was `...11.108`).
|
|
19
|
+
- **Sealed PhiC31 pseudo-attP recall benchmark** (`benchmarks/offtarget/integrase/`, O-G2): does attP-sequence-
|
|
20
|
+
similarity recover the documented pseudo-attP above length-matched GRCh38 background? **Result — NEGATIVE,
|
|
21
|
+
reported verbatim:** all three sites score 14 mm / 30 bp (53.3% identity), exactly the background **median**
|
|
22
|
+
(60.6% / 77.0% / 82.4% of random windows are as-or-more attP-similar). Sequence identity to attP is **not** a
|
|
23
|
+
validated PhiC31 pseudo-attP predictor — φC31 recognition depends on palindromic architecture (Chalberg 2006) /
|
|
24
|
+
a learned model (IntQuery), not raw identity.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **Integrase status corrected: `semi_validated` → `mechanism_based_unvalidated` (with a sealed-NEGATIVE benchmark).**
|
|
28
|
+
The v7.2.0 "semi-validated (documented pseudosites as partial ground truth)" implied the sites validated the
|
|
29
|
+
method; the sealed benchmark shows they do not. This is a *stronger, more honest* outcome — a tested negative
|
|
30
|
+
rather than an untested claim. The verified att + documented pseudosites remain grounded facts and are surfaced
|
|
31
|
+
as verified known off-target loci. `nominate_integrase` PhiC31 returns the documented pseudo-attP + the sealed
|
|
32
|
+
benchmark; Bxb1 returns genome-wide similarity candidates carrying the same `similarity_ranking_validated: false`
|
|
33
|
+
caveat. Prereg O-G2 amended + re-SHA-locked; data card + deviations ledger updated; Off-Target page shows the
|
|
34
|
+
documented sites + the benchmark verdict.
|
|
35
|
+
|
|
36
|
+
## [7.2.0] - 2026-07-01 - PEN-OFFTGT v2: Stage E becomes a genome-wide, per-mechanism off-target FINDER (all 5 writer classes)
|
|
37
|
+
|
|
38
|
+
Stage E was a candidate *scorer* — it ranked off-target sites you supplied. A real off-target tool (CRISPOR /
|
|
39
|
+
CHOPCHOP) takes a guide/target and *finds* the genome-wide off-target set itself. PEN-OFFTGT v2 closes that
|
|
40
|
+
enumeration gap AND applies the **correct off-target mechanism for each writer class**, each carrying a truthful
|
|
41
|
+
per-mechanism validation status (O-WS0–O-WS9 of the plan).
|
|
42
|
+
|
|
43
|
+
### Per-mechanism paths (O-WS3–O-WS6)
|
|
44
|
+
- **Serine integrase** (`offtarget_integrase.py`, O-WS3): a genome-wide **pseudo-attP** scan — a fixed-sequence
|
|
45
|
+
Cas-OFFinder scan of the attP core window over GRCh38, scored by att-arm similarity. **Bxb1** is fully encoded
|
|
46
|
+
(FlyBase FBto0000359 / Ghosh 2003) and is highly specific. Status **semi-validated**. **PhiC31 is a disclosed
|
|
47
|
+
data gap** (its documented human pseudo-attP set — Chalberg 2006 — could not be verified from an open source in
|
|
48
|
+
this build, so it abstains rather than fabricate). `data/curated/integrase_att.yaml`.
|
|
49
|
+
- **Bridge** (`offtarget_bridge.py`, O-WS4): wraps the existing DMS-scored genome scan (measured Perry-2025
|
|
50
|
+
specificity, held-out ranking AUROC 0.88). Status **hard-locked mechanism-based-unvalidated** — the ranker is
|
|
51
|
+
DMS-validated but **no genome-wide cellular off-target assay exists** for bridge recombinases, so genomic
|
|
52
|
+
recovery is unvalidated (stated in a no-ground-truth disclosure).
|
|
53
|
+
- **CAST** (`offtarget_cast.py` + `data/curated/cast_systems.yaml`, O-WS5) — NEW: guide-directed spacer scan +
|
|
54
|
+
the distinctive **guide-independent untargeted-transposition** background per system (ShCAST/Type V-K high +
|
|
55
|
+
AT-biased; VchCAST/Type I-F >95–99% on-target), all DOI-tagged. Status **mechanism-based-unvalidated**.
|
|
56
|
+
- **PASTE / (ee)PASSIGE** (`offtarget_paste.py`, O-WS6) — NEW: composes the validated nuclease finder (Cas9
|
|
57
|
+
nickase, pegRNA) with the semi-validated integrase pseudo-attP scan (installed att); returns both component sets
|
|
58
|
+
and recommends BOTH a nuclease assay and an integrase assay. Status **composite**.
|
|
59
|
+
|
|
60
|
+
### Status labels + assay recommender (O-WS7) + disclosures (O-WS8 / gate O-G3)
|
|
61
|
+
- Every nomination carries a per-mechanism status label + the mechanism-appropriate confirm assay; `recommend_assay`
|
|
62
|
+
now covers CAST (transposon insertion-site seq) and PASTE (dual). `docs/cards/offtarget_data.md` documents the
|
|
63
|
+
per-mechanism ground-truth status — **O-G3: every mechanism has either a sealed benchmark (nuclease) or an
|
|
64
|
+
explicit no-ground-truth / data-gap disclosure (integrase-PhiC31, bridge, CAST) — never a fabricated metric.**
|
|
65
|
+
- Disclosed deviations from the plan (no silent substitution): `att_pwm.json` → an att-similarity model in
|
|
66
|
+
`integrase_att.yaml` (a per-position PWM needs aligned pseudosites that do not exist at genome scale);
|
|
67
|
+
`bridge_dms_specificity.parquet` → the existing measured `bridge_offtarget_profile_measured.parquet` is reused;
|
|
68
|
+
`known_pseudosites.parquet` → not created (Bxb1 highly specific; PhiC31 disclosed data gap).
|
|
69
|
+
|
|
70
|
+
### Nuclease finder (O-WS0–O-WS2)
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
- **Genome-wide enumeration engine** (`pen_stack/wgenome/offtarget_enumerate.py`, O-WS1). Given a guide + enzyme,
|
|
74
|
+
enumerates every genomic site within the mismatch tolerance across GRCh38 via **Cas-OFFinder** (Bae, Park & Kim,
|
|
75
|
+
Bioinformatics 2014, `10.1093/bioinformatics/btu048`), returning coordinates, strand, matched sequence, and
|
|
76
|
+
mismatch count. Supports SpCas9 (NGG), SaCas9 (NNGRRT), and Cas12a (TTTV, 5' PAM). A full scan is heavy, so it
|
|
77
|
+
runs **only on the VM** (`casoffinder:tools` Docker image, `docker/casoffinder.Dockerfile`); the live app
|
|
78
|
+
**replays a committed coordinate cache** for the canonical guides or **abstains honestly** for a novel one
|
|
79
|
+
(never fabricates sites) — the same replay-or-abstain pattern as the heavy structure oracles. The enumerated
|
|
80
|
+
coordinates are facts from the public GRCh38 assembly (no license restriction), so the cache is committed
|
|
81
|
+
(`data/offtarget/enumerated_cache.parquet`, 8 canonical guides, 40,268 sites).
|
|
82
|
+
- **Nuclease off-target FINDER** (`pen_stack/wgenome/offtarget_nuclease.py`, O-WS2): chains enumeration into the
|
|
83
|
+
existing, validated scorer — real CRISOT-Score → mismatch-calibrated risk band → chromatin annotation — so a
|
|
84
|
+
guide returns the genome-wide ranked off-target set *with coordinates*. Scoring is unchanged from v6.10 (still
|
|
85
|
+
validated: CRISOT beats homology on four unbiased assays); v2 adds the enumeration front end.
|
|
86
|
+
- **O-G1 gate PASSED**: enumeration recovers **100%** of EMX1's documented GUIDE-seq off-targets within the ≤5-mm
|
|
87
|
+
tolerance (all 16 validated-active sites, which are all ≤4 mm; the higher-mismatch fixture rows are inactive
|
|
88
|
+
negatives). The on-target is recovered at chr2:72,933,852. `tests/unit/test_ws_offtarget2.py`.
|
|
89
|
+
- **Prereg** `prereg/ws_offtarget2.yaml` (SHA-locked): the mechanism taxonomy, per-enzyme enumeration parameters,
|
|
90
|
+
the truthful per-mechanism status-label rules (validated / semi-validated / mechanism-based-unvalidated), and
|
|
91
|
+
the O-G1/G2/G3 gates.
|
|
92
|
+
- REST: `POST /offtarget` is now a **finder by default** for a nuclease guide with no supplied `candidate_sites`
|
|
93
|
+
(accepts `enzyme`, `max_mismatch`); `GET /offtarget/enumerated` lists the cached guides. The web **Off-Target**
|
|
94
|
+
page is rebuilt as a finder (guide in → genome-wide ranked off-targets with coordinates), with the scorer→finder
|
|
95
|
+
explanation and the VM/cache architecture stated.
|
|
96
|
+
|
|
97
|
+
### Unchanged / backward compatible
|
|
98
|
+
- Supplying `candidate_sites` keeps the v6.10 score-my-candidates path. The integrase (pseudo-attB sequence scan),
|
|
99
|
+
bridge (Perry-DMS), chromatin annotation, and validation-assay recommender are unchanged. Nomination remains a
|
|
100
|
+
candidate, never a clearance.
|
|
101
|
+
|
|
6
102
|
## [7.1.8] - 2026-06-30 - Writer immunogenicity moves to the Writer Atlas; SpCas9 removed from the writer options
|
|
7
103
|
|
|
8
104
|
### Changed
|
|
@@ -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: 7.1
|
|
5
|
-
date-released: 2026-
|
|
4
|
+
version: 7.2.1
|
|
5
|
+
date-released: 2026-07-02
|
|
6
6
|
authors:
|
|
7
7
|
- family-names: "Mahaboob Ali"
|
|
8
8
|
given-names: "Anees Ahmed"
|
|
@@ -5,6 +5,7 @@ include README.md LICENSE CHANGELOG.md CITATION.cff pyproject.toml
|
|
|
5
5
|
recursive-include configs *.yaml *.yml *.txt.example *.fasta
|
|
6
6
|
recursive-include prereg *.yaml *.json
|
|
7
7
|
recursive-include data/curated *
|
|
8
|
+
recursive-include data/offtarget *.parquet
|
|
8
9
|
recursive-include benchmarks *.yaml *.md SHA256SUMS
|
|
9
10
|
recursive-include bench *.py
|
|
10
11
|
recursive-include docs *.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pen-stack
|
|
3
|
-
Version: 7.1
|
|
3
|
+
Version: 7.2.1
|
|
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
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# PhiC31 pseudo-attP recall benchmark (O-G2) — SEALED
|
|
2
|
+
|
|
3
|
+
**Question:** does attP-sequence-similarity recover the documented human pseudo-attP above random genomic background?
|
|
4
|
+
|
|
5
|
+
**Data (all independently verified against NCBI/RCSB):**
|
|
6
|
+
- **Positives** — `phic31_pseudo.fasta`: human pseudo-attP ψA/ψC/ψD, GenBank **AF333429/AF333430/AF333431**
|
|
7
|
+
(Thyagarajan 2001, *Mol Cell Biol* 21(12), PMID 11359900, DOI `10.1128/MCB.21.12.3926-3934.2001`; chr8/16/15).
|
|
8
|
+
- **Query** — the phage φC31 attP central 30 bp from **PDB 9U2T (attP60)**, the "PhiC31 integrase-attB-attP synaptic
|
|
9
|
+
complex" structure; the canonical Groth-2000 34 bp attB is present in **PDB 9U2S (attB53)** (Groth 2000, PNAS,
|
|
10
|
+
DOI `10.1073/pnas.090527097`).
|
|
11
|
+
- **Background** — 1000 GC/N-filtered, length-matched random GRCh38 windows per positive.
|
|
12
|
+
|
|
13
|
+
**Result (`phic31_recall_metrics.json`) — NEGATIVE, reported verbatim:** every documented pseudosite scores 14 mm /
|
|
14
|
+
30 bp (53.3% identity), which is exactly the **background median** (14 mm); 60.6% / 77.0% / 82.4% of random windows
|
|
15
|
+
are as-or-more attP-similar. Sequence identity to attP does **not** recover the documented pseudo-attP above
|
|
16
|
+
background — consistent with the field (φC31 pseudosite recognition depends on palindromic architecture, Chalberg
|
|
17
|
+
2006 DOI `10.1016/j.jmb.2005.11.098`, / a learned model, IntQuery). The integrase genome-wide pseudo-attP
|
|
18
|
+
**similarity ranking is therefore unvalidated**; the verified att and documented pseudosites remain grounded facts.
|
|
19
|
+
|
|
20
|
+
**Honest limits:** N=3 (the open GenBank subset; the full Chalberg 19-site set is paywalled); tests
|
|
21
|
+
sequence-identity only (no palindrome/learned model); deterministic (seed 20260701), pysam over GRCh38.
|
|
22
|
+
|
|
23
|
+
Run: `docker run --rm --entrypoint bash -v <genomes>:/genome -v $PWD:/work -w /work penstack:phase1.5 -lc 'python harness.py'`
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
701efce23441ba6ec3865060aa3a749d7165d013628f3ed8010737861b306557 README.md
|
|
2
|
+
888dd4ba69bbe1eccd323797adc89b242b1c8ec6208a5f9f41df839d641d10e6 harness.py
|
|
3
|
+
fe23827ff34204bc2cd1f903fcd3e32b120c4521787342e6590824249573a4d4 phic31_pseudo.fasta
|
|
4
|
+
2a0f22d700f0db0bafd1c98b8b8893f14e86ae9574ff789042bd3ad1c7f6a3c0 phic31_recall_metrics.json
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# CRISPR-associated transposase (CAST) systems — per-system off-target properties (PEN-OFFTGT v2, O-WS5).
|
|
2
|
+
#
|
|
3
|
+
# CAST off-target has TWO distinct modes, and the balance differs by system type:
|
|
4
|
+
# 1. guide-directed — integration at genomic sites matching the crRNA spacer (a sequence-match scan, like a
|
|
5
|
+
# nuclease off-target, but the transposon inserts ~49-66 bp downstream of the protospacer).
|
|
6
|
+
# 2. guide-INDEPENDENT untargeted transposition — the Tn7-like transposase machinery (TnsB/TnsC/TniQ) inserting
|
|
7
|
+
# WITHOUT the CRISPR effector or the guide. This is the DISTINCTIVE, dominant off-target mode
|
|
8
|
+
# for Type V-K systems (ShCAST) and is largely absent in Type I-F systems (VchCAST).
|
|
9
|
+
#
|
|
10
|
+
# All values are DOCUMENTED facts from the primary literature (DOIs below), reported as a qualitative tier plus the
|
|
11
|
+
# published on-target fidelity where a number is stated. This is NOT a genome-wide cellular off-target assay
|
|
12
|
+
# (none exists for CAST at genome scale) -> status is mechanism_based_unvalidated; the confirming assay is
|
|
13
|
+
# transposon insertion-site sequencing.
|
|
14
|
+
|
|
15
|
+
version: "1.0"
|
|
16
|
+
|
|
17
|
+
systems:
|
|
18
|
+
ShCAST:
|
|
19
|
+
full_name: "Scytonema hofmanni CAST"
|
|
20
|
+
cast_type: "V-K"
|
|
21
|
+
effector: "Cas12k"
|
|
22
|
+
untargeted_transposition: high # guide/Cas12k-INDEPENDENT, AT-biased (the dominant off-target mode)
|
|
23
|
+
guide_independent: true
|
|
24
|
+
at_biased_untargeted: true
|
|
25
|
+
on_target_fidelity_note: "up to ~80% integration in E. coli without selection, but LOW fidelity: prone to
|
|
26
|
+
extensive RNA-independent (guide-independent) transposition via TnsB/TnsC/TniQ; improved vectors that
|
|
27
|
+
suppress the RNA-independent pathway raise specificity up to 98.1% (Type V-K)."
|
|
28
|
+
dois:
|
|
29
|
+
- "10.1126/science.aax9181" # Strecker et al. 2019, ShCAST (Science) — RNA-guided DNA insertion with CAST
|
|
30
|
+
- "10.1126/science.adj8543" # Type V-K target-site selection + untargeted mechanism (Science 2024)
|
|
31
|
+
VchCAST:
|
|
32
|
+
full_name: "Vibrio cholerae CAST (Tn6677 / INTEGRATE)"
|
|
33
|
+
cast_type: "I-F"
|
|
34
|
+
effector: "Cascade (Cas6-Cas7-Cas8/Cas5) + TniQ"
|
|
35
|
+
untargeted_transposition: low # high fidelity; guide-independent transposition largely absent
|
|
36
|
+
guide_independent: false
|
|
37
|
+
at_biased_untargeted: false
|
|
38
|
+
on_target_fidelity_note: "remarkable fidelity — the majority of crRNAs direct >95% on-target integration and
|
|
39
|
+
many exceed 99%; up to ~100% integration efficiency of cargo up to ~10 kb in bacteria."
|
|
40
|
+
dois:
|
|
41
|
+
- "10.1038/s41586-019-1323-z" # Klompe et al. 2019, VchCAST / Tn6677 (Nature)
|
|
42
|
+
- "10.1038/s41587-020-00745-y" # Vo et al. 2021, INTEGRATE high-efficiency multiplexed (Nat Biotechnol)
|
|
43
|
+
evoCAST:
|
|
44
|
+
full_name: "evolved Scytonema hofmanni CAST (PACE-evolved)"
|
|
45
|
+
cast_type: "V-K"
|
|
46
|
+
effector: "Cas12k (evolved)"
|
|
47
|
+
untargeted_transposition: moderate # directed evolution improved specificity over WT ShCAST
|
|
48
|
+
guide_independent: true
|
|
49
|
+
at_biased_untargeted: true
|
|
50
|
+
on_target_fidelity_note: "evolved Type V-K CAST with substantially improved on-target integration in human
|
|
51
|
+
cells; guide-independent transposition is reduced relative to WT ShCAST but not eliminated."
|
|
52
|
+
dois:
|
|
53
|
+
- "10.1126/science.adr8492" # Tou et al. 2025, evoCAST (Science) — evolved CAST for human-cell insertion
|
|
54
|
+
- "10.1038/s41587-023-01748-1" # Lampe et al. 2024, targeted integration in human cells without DSBs (Nat Biotechnol)
|
|
55
|
+
|
|
56
|
+
# scope: human-cell CAST is emerging (evoCAST 2025); the untargeted-transposition rates above are characterised in
|
|
57
|
+
# bacteria / biochemically. No genome-wide unbiased CELLULAR off-target assay exists for human-cell CAST -> the
|
|
58
|
+
# genomic predictions are mechanism-based, unvalidated; confirm with transposon insertion-site sequencing.
|
|
59
|
+
confirm_assay: "transposon insertion-site sequencing (e.g. Tn-seq / integration-site amplicon sequencing)"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Serine-integrase attachment sites for the genome-wide pseudo-att off-target scan (PEN-OFFTGT v2, O-WS3).
|
|
2
|
+
#
|
|
3
|
+
# A serine integrase recombines a donor attB with a genomic pseudo-attP resembling the phage attP. The off-target
|
|
4
|
+
# scan enumerates genomic sites similar to the attP core region (a fixed-sequence Cas-OFFinder scan over GRCh38,
|
|
5
|
+
# tolerating mismatches), then scores each by att-arm similarity. Confirming assay: Cryptic-seq / HIDE-seq.
|
|
6
|
+
#
|
|
7
|
+
# HONEST STATUS (v7.2.1): the att sequences and the documented human pseudo-attP are VERIFIED grounded facts, but a
|
|
8
|
+
# SEALED recall benchmark on the best-documented pseudosites (PhiC31 psiA/psiC/psiD) is NEGATIVE — att-sequence-
|
|
9
|
+
# similarity does NOT recover them above random background (see PhiC31.recall_benchmark below). So the genome-wide
|
|
10
|
+
# pseudo-attP SIMILARITY RANKING is a mechanism-based scan that is NOT validated as a predictor; it is honestly
|
|
11
|
+
# labelled as such, not "semi-validated." The documented pseudosites are surfaced as verified known-off-target loci.
|
|
12
|
+
#
|
|
13
|
+
# DEVIATION (disclosed): the prereg named `att_pwm.json`. A position-weight MATRIX requires many aligned pseudosite
|
|
14
|
+
# sequences to estimate per-position tolerance; that alignment does not exist at genome scale for these integrases.
|
|
15
|
+
# So the scan uses att-arm SIMILARITY (mismatch count to the documented att, core-anchored) rather than a fitted
|
|
16
|
+
# PWM — a mechanism-based similarity model, honestly labelled, not a fabricated per-position matrix.
|
|
17
|
+
|
|
18
|
+
version: "1.0"
|
|
19
|
+
|
|
20
|
+
integrases:
|
|
21
|
+
Bxb1:
|
|
22
|
+
origin: "phage Bxb1 (Mycobacterium)"
|
|
23
|
+
attB: "TCGGCCGGCTTGTCGACGACGGCGGTCTCCGTCGTCAGGATCATCCGGGC"
|
|
24
|
+
attP: "GTCGTGGTTTGTCTGGTCAACCACCGCGGTCTCAGTGGTGTACGGTACAAACCCCGAC"
|
|
25
|
+
core: "GCGGTCTC"
|
|
26
|
+
central_dinucleotide: "GT"
|
|
27
|
+
# 34-nt attP window centred on the core — the fixed sequence scanned genome-wide for pseudo-attP
|
|
28
|
+
scan_window: "CTGGTCAACCACCGCGGTCTCAGTGGTGTACGGT"
|
|
29
|
+
scan_max_mismatch: 8
|
|
30
|
+
specificity_note: "Bxb1 is highly specific — very few genomic pseudo-attP in human cells (a reason it is the
|
|
31
|
+
integrase of choice for PASTE/PASSIGE). The scan therefore returns few high-similarity candidates."
|
|
32
|
+
source: "FlyBase FBto0000359/358; Ghosh, Kim & Hatfull, Mol Cell 2003"
|
|
33
|
+
doi: "10.1016/S1097-2765(03)00444-1"
|
|
34
|
+
|
|
35
|
+
# PhiC31 — now ENCODED with independently-verified sequences (v7.2.1, closes the O-WS3 data gap). att from the
|
|
36
|
+
# phiC31 integrase-attB-attP synaptic-complex structure (PDB 9U2T attP60 / 9U2S attB53; the canonical Groth-2000
|
|
37
|
+
# 34 bp attB is present in attB53); documented human pseudo-attP from Thyagarajan 2001 (GenBank AF333429/30/31).
|
|
38
|
+
PhiC31:
|
|
39
|
+
origin: "phage phiC31 (Streptomyces)"
|
|
40
|
+
attB: "GTGCCAGGGCGTGCCCTTGGGCTCCCCGGGCGCG" # canonical 34 bp minimal attB (verified inside PDB 9U2S attB53)
|
|
41
|
+
attP: "CGGGAGTAGTGCCCCAACTGGGGTAACCTTTGAGTTCTCTCAGTTGGGGGCGTAGGGTCG" # PDB 9U2T attP60 (60 bp)
|
|
42
|
+
core: "TTG"
|
|
43
|
+
central_dinucleotide: "TT"
|
|
44
|
+
scan_window: "AACTGGGGTAACCTTTGAGTTCTCTCAGTT" # attP central 30 bp (localises to the psiA recombination core)
|
|
45
|
+
scan_max_mismatch: 8
|
|
46
|
+
source: "Groth et al., PNAS 2000; PDB 9U2T/9U2S (phiC31 integrase-attB-attP synaptic complex)"
|
|
47
|
+
doi: "10.1073/pnas.090527097"
|
|
48
|
+
pdb: ["9U2T", "9U2S"]
|
|
49
|
+
# documented human pseudo-attP positive set (verified GenBank; the integration loci)
|
|
50
|
+
pseudo_attP_positive_set:
|
|
51
|
+
- {name: psiA, genbank: AF333429, chrom: chr8}
|
|
52
|
+
- {name: psiC, genbank: AF333430, chrom: chr16}
|
|
53
|
+
- {name: psiD, genbank: AF333431, chrom: chr15}
|
|
54
|
+
positive_set_source: "Thyagarajan et al., Mol Cell Biol 21(12), 2001"
|
|
55
|
+
positive_set_doi: "10.1128/MCB.21.12.3926-3934.2001"
|
|
56
|
+
# SEALED recall benchmark (O-G2) — result reported VERBATIM: benchmarks/offtarget/integrase/phic31_recall_metrics.json
|
|
57
|
+
recall_benchmark:
|
|
58
|
+
recovered_above_background: false
|
|
59
|
+
verdict: "NEGATIVE — attP-sequence-similarity does NOT recover the documented pseudo-attP above random
|
|
60
|
+
background (all 3 sites at 14 mm / 30 bp = the background median; 60.6/77.0/82.4% of background as-or-more
|
|
61
|
+
similar). Sequence identity alone is not a validated PhiC31 pseudo-attP predictor; recognition depends on
|
|
62
|
+
palindromic architecture (Chalberg 2006, 10.1016/j.jmb.2005.11.098) / a learned model (IntQuery)."
|
|
63
|
+
metrics: "benchmarks/offtarget/integrase/phic31_recall_metrics.json"
|
|
64
|
+
specificity_note: "PhiC31 is a PROMISCUOUS serine integrase with documented human pseudo-attP (unlike Bxb1).
|
|
65
|
+
The sealed recall benchmark (above) is NEGATIVE: the att-similarity scan does not distinguish the documented
|
|
66
|
+
pseudosites from background, so the genome-wide similarity RANKING is unvalidated (honest negative)."
|
|
Binary file
|
|
Binary file
|
|
@@ -90,3 +90,28 @@ candidate ENUMERATION needs the on-VM Cas-OFFinder/genome scan; this benchmark c
|
|
|
90
90
|
candidates. Bridge/integrase off-target is data-thin: there is **no published genome-wide unbiased off-target assay
|
|
91
91
|
or predictor for bridge recombinases** (verified), and the large-serine-integrase assays (Cryptic-seq/HIDE-seq) and
|
|
92
92
|
predictor (IntQuery) are recent single-company preprints with no public weights.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## v7.2 (PEN-OFFTGT v2) — per-mechanism ground-truth status (O-WS8 / gate O-G3)
|
|
97
|
+
|
|
98
|
+
Stage E is now a genome-wide **finder** (Cas-OFFinder over GRCh38; heavy scan on the VM, cached coordinates
|
|
99
|
+
replayed by the app). Each writer class applies the correct off-target mechanism and carries a **truthful
|
|
100
|
+
validation status** — a sealed benchmark where ground truth exists, an explicit **no-genome-wide-ground-truth
|
|
101
|
+
disclosure** where it does not. No mechanism is ever presented as validated where the data cannot support it.
|
|
102
|
+
|
|
103
|
+
| Writer class | Mechanism | Enumeration | Status | Ground truth / benchmark |
|
|
104
|
+
|---|---|---|---|---|
|
|
105
|
+
| **Nuclease** (SpCas9/SaCas9/Cas12a) | mismatch-tolerant cleavage at protospacer+PAM | Cas-OFFinder genome scan | ✅ **validated** | 4-assay Off-Target-Bench (above) + **O-G1**: enumeration recovers 100% of EMX1's documented GUIDE-seq off-targets ≤5 mm |
|
|
106
|
+
| **Serine integrase** (Bxb1, PhiC31) | recombination at genomic pseudo-attP | fixed-sequence att-window scan | 🔵 **mechanism-based, sealed-NEGATIVE benchmark** (v7.2.1) | att verified (Bxb1: FlyBase FBto0000359 / Ghosh 2003 `10.1016/S1097-2765(03)00444-1`; PhiC31: **PDB 9U2T/9U2S** + Groth 2000 `10.1073/pnas.090527097`); the PhiC31 human pseudo-attP set is verified (Thyagarajan 2001, **GenBank AF333429/30/31**, `10.1128/MCB.21.12.3926-3934.2001`; chr8/16/15). The v7.2.1 **SEALED recall benchmark** (`benchmarks/offtarget/integrase/`) is **NEGATIVE**: att-sequence-similarity does NOT recover the documented pseudo-attP above random background (all three at 14 mm / 30 bp = the background median). The genome-wide similarity RANKING is therefore **unvalidated** — φC31 recognition needs palindromic architecture (Chalberg 2006, `10.1016/j.jmb.2005.11.098`) / a learned model (IntQuery), not raw identity. Documented pseudosites surfaced as verified known loci; the negative is reported verbatim (a stronger, more honest O-G2 than an untested "semi-validated"). |
|
|
107
|
+
| **Bridge** (IS110/IS621) | recombination at bridge-RNA target-loop matches | core-seeded genome scan (pysam) | 🔵 **mechanism-based, unvalidated** | **NO genome-wide unbiased CELLULAR off-target assay exists** (technology ~2024). The mismatch-tolerance RANKER is validated on the measured Perry-2025 in-vitro DMS specificity (held-out ranking AUROC 0.88), but genomic recovery is unvalidated. |
|
|
108
|
+
| **CAST** (ShCAST V-K / VchCAST I-F) | guide-directed integration + guide-independent untargeted transposition | spacer scan + per-system untargeted background | 🔵 **mechanism-based, unvalidated** | untargeted-transposition rates documented per system (`data/curated/cast_systems.yaml`): ShCAST high/AT-biased (Strecker 2019 `10.1126/science.aax9181`; Science 2024 `10.1126/science.adj8543`), VchCAST >95–99% on-target (Klompe 2019 `10.1038/s41586-019-1323-z`; Vo 2021 `10.1038/s41587-020-00745-y`). No genome-wide cellular assay for human-cell CAST. |
|
|
109
|
+
| **PASTE / (ee)PASSIGE** | Cas9-nickase off-target + integrase pseudo-attP | compose(nuclease, integrase) | composite (✅ nickase + 🟡 integrase) | inherits the nuclease benchmark for the nickase and the integrase status for the installed att; recommends BOTH a nuclease assay AND an integrase assay |
|
|
110
|
+
|
|
111
|
+
**O-G3 satisfied:** every mechanism has either a sealed benchmark (nuclease) or an explicit no-ground-truth /
|
|
112
|
+
data-gap disclosure (integrase-PhiC31, bridge, CAST) — never a fabricated metric. The bridge and CAST paths are
|
|
113
|
+
**hard-locked** to 🔵 unvalidated in code.
|
|
114
|
+
|
|
115
|
+
**Honest limits (v7.2):** enumeration recall depends on the mismatch tolerance (≤5 mm nuclease, ≤8 mm integrase
|
|
116
|
+
att window); very divergent off-targets can be missed (a limitation shared with CRISPOR). DNA/RNA bulges are not
|
|
117
|
+
enumerated in v2.0 (substitutions only). The engine nominates and ranks; it does not clear a design.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""PEN-STACK v3.0 - open infrastructure for genome writing."""
|
|
2
|
-
__version__ = "7.1
|
|
2
|
+
__version__ = "7.2.1"
|
|
@@ -156,14 +156,17 @@ def immune_profile(design: dict) -> dict:
|
|
|
156
156
|
|
|
157
157
|
@mcp.tool()
|
|
158
158
|
def offtarget_scan(writer_family: str, guide: str | None = None, candidate_sites: list | None = None,
|
|
159
|
-
sequence: str | None = None, assay: str = "guideseq"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
sequence: str | None = None, assay: str = "guideseq", enzyme: str | None = None,
|
|
160
|
+
max_mismatch: int = 5) -> dict:
|
|
161
|
+
"""PEN-OFFTGT v2 genome-wide, per-mechanism off-target FINDER (NOT a clearance). For a nuclease guide it
|
|
162
|
+
enumerates the genome-wide off-target set over GRCh38 (Cas-OFFinder, cached) + real CRISOT + risk + chromatin
|
|
163
|
+
(validated); serine integrase = genome-wide pseudo-attP scan (semi-validated); bridge = DMS-scored scan
|
|
164
|
+
(mechanism-based, unvalidated); CAST = guide-directed + untargeted-transposition background (unvalidated);
|
|
165
|
+
PASTE = nuclease + integrase composition. Each carries a truthful status label + the confirming assay.
|
|
166
|
+
Abstains for a novel input (VM scan); never fabricates sites."""
|
|
164
167
|
from pen_stack.wgenome.offtarget_predict import nominate_offtargets
|
|
165
168
|
return nominate_offtargets(writer_family, guide=guide, candidate_sites=candidate_sites,
|
|
166
|
-
sequence=sequence, assay=assay)
|
|
169
|
+
sequence=sequence, assay=assay, enzyme=enzyme, max_mismatch=max_mismatch)
|
|
167
170
|
|
|
168
171
|
|
|
169
172
|
@mcp.tool()
|
|
@@ -50,11 +50,13 @@ _TOOLS = [
|
|
|
50
50
|
"efficiency w/ conformal interval + auto-designed guide/att (v6.8 PEN-WRITER)",
|
|
51
51
|
"input": "write request (write-type, cargo, cell type, optional target/donor seq)", "output": "WriterRanking",
|
|
52
52
|
"entrypoint": "pen_stack.atlas.writer_recommend.recommend_writers", "fabricates": False},
|
|
53
|
-
{"name": "nominate_offtargets", "summary": "
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
53
|
+
{"name": "nominate_offtargets", "summary": "genome-wide, per-mechanism off-target FINDER (v7.2 PEN-OFFTGT v2): "
|
|
54
|
+
"enumerates the off-target set over GRCh38 (Cas-OFFinder) and applies the correct mechanism per writer class "
|
|
55
|
+
"- nuclease cleavage (validated: CRISOT + risk + chromatin), integrase pseudo-attP (semi-validated), bridge "
|
|
56
|
+
"target-specificity (unvalidated), CAST guide + untargeted transposition (unvalidated), PASTE composition - "
|
|
57
|
+
"each with a truthful status label; nomination is NOT a clearance",
|
|
58
|
+
"input": "writer family + guide/target (enumerated genome-wide) or supplied candidate sites",
|
|
59
|
+
"output": "genome-wide ranked off-target candidates + per-mechanism status + calibrated risk + validation assay",
|
|
58
60
|
"entrypoint": "pen_stack.wgenome.offtarget_predict.nominate_offtargets", "fabricates": False},
|
|
59
61
|
{"name": "recommend_delivery", "summary": "cross-modality delivery recommender: rank vehicles by cargo-form + "
|
|
60
62
|
"safety<->efficacy + a grounded serotype->tissue tropism prior (approved therapies) + the learned FLIP-AAV "
|
|
@@ -374,15 +374,19 @@ def immune_endpoint(design: dict):
|
|
|
374
374
|
|
|
375
375
|
@app.post("/offtarget", tags=["v6.10 off-target"])
|
|
376
376
|
def offtarget_endpoint(req: dict):
|
|
377
|
-
"""
|
|
378
|
-
{writer_family, guide?, candidate_sites?, sequence?, accessibility?, assay?}.
|
|
379
|
-
|
|
380
|
-
|
|
377
|
+
"""PEN-OFFTGT cross-family off-target NOMINATION (NOT a clearance). Body:
|
|
378
|
+
{writer_family, guide?, enzyme?, max_mismatch?, candidate_sites?, sequence?, accessibility?, assay?}.
|
|
379
|
+
|
|
380
|
+
v7.2 (finder): for a nuclease guide with NO ``candidate_sites``, enumerates the genome-wide off-target set
|
|
381
|
+
over GRCh38 (Cas-OFFinder, replayed from the committed cache) and ranks it by the real CRISOT-Score +
|
|
382
|
+
mismatch-calibrated risk + chromatin annotation - the CRISPOR-like default. Supplying ``candidate_sites``
|
|
383
|
+
keeps the v6.10 score-my-candidates path. Abstains (never fabricates) for a novel guide with no VM scan."""
|
|
381
384
|
from pen_stack.wgenome.offtarget_predict import nominate_offtargets
|
|
382
385
|
return nominate_offtargets(
|
|
383
386
|
req.get("writer_family", ""), guide=req.get("guide"), candidate_sites=req.get("candidate_sites"),
|
|
384
387
|
sequence=req.get("sequence"), accessibility=req.get("accessibility"),
|
|
385
|
-
target_core=req.get("target_core"), assay=req.get("assay", "guideseq")
|
|
388
|
+
target_core=req.get("target_core"), assay=req.get("assay", "guideseq"),
|
|
389
|
+
enzyme=req.get("enzyme"), max_mismatch=int(req.get("max_mismatch", 5)))
|
|
386
390
|
|
|
387
391
|
|
|
388
392
|
@app.get("/offtarget/assay", tags=["v6.10 off-target"])
|
|
@@ -392,6 +396,20 @@ def offtarget_assay_endpoint(writer_family: str):
|
|
|
392
396
|
return recommend_assay(writer_family)
|
|
393
397
|
|
|
394
398
|
|
|
399
|
+
@app.get("/offtarget/enumerated", tags=["v6.10 off-target"])
|
|
400
|
+
def offtarget_enumerated_endpoint():
|
|
401
|
+
"""v7.2: the guides whose genome-wide off-target enumeration is CACHED (so the finder works here without a VM
|
|
402
|
+
scan). A novel guide abstains (its scan runs on the VM). Enumerated coordinates are public-genome facts."""
|
|
403
|
+
from pen_stack.wgenome.offtarget_data import CANONICAL_GUIDES
|
|
404
|
+
from pen_stack.wgenome.offtarget_enumerate import enumerated_guides
|
|
405
|
+
cached = enumerated_guides()
|
|
406
|
+
seq2name = {v: k for k, v in CANONICAL_GUIDES.items()}
|
|
407
|
+
return {"enzyme": "SpCas9",
|
|
408
|
+
"guides": [{"guide": g, "name": seq2name.get(g, g), "enzyme": e} for e, g in cached],
|
|
409
|
+
"note": ("genome-wide enumeration for these guides is replayed from the committed GRCh38 Cas-OFFinder "
|
|
410
|
+
"cache; a novel guide requires an on-VM scan (the finder abstains rather than fabricate).")}
|
|
411
|
+
|
|
412
|
+
|
|
395
413
|
@app.get("/campaign", tags=["v7.0 closed-loop"])
|
|
396
414
|
def campaign_endpoint():
|
|
397
415
|
"""v7.0 Stage J: the validation-campaign engine. Returns the expression-validation campaign: the next batch of
|
|
@@ -29,7 +29,7 @@ def recommend_assay(writer_family: str) -> dict:
|
|
|
29
29
|
"in the target cell type (GUIDE-seq), chromatin masks a fraction of in vitro sites",
|
|
30
30
|
"available": True,
|
|
31
31
|
"note": "nomination ranks CANDIDATES; an empirical assay is required for clearance."}
|
|
32
|
-
if "integrase" in fam or "
|
|
32
|
+
if ("integrase" in fam or "bxb1" in fam or "phic31" in fam) and "paste" not in fam and "passige" not in fam:
|
|
33
33
|
return {"family": writer_family, "writer_class": "large serine integrase",
|
|
34
34
|
"recommended": [{"assay": "Cryptic-seq / HIDE-seq", "setting": "unbiased LSI off-target discovery",
|
|
35
35
|
"doi": "10.1101/2024.08.23.609471",
|
|
@@ -39,6 +39,29 @@ def recommend_assay(writer_family: str) -> dict:
|
|
|
39
39
|
"quantitative prediction (IntQuery) is paper-only (no public weights)",
|
|
40
40
|
"available": True,
|
|
41
41
|
"note": "LSI off-target assays are recent preprints; coverage is single-company / largely Bxb1."}
|
|
42
|
+
if "paste" in fam or "passige" in fam:
|
|
43
|
+
return {"family": writer_family, "writer_class": "prime-editing integrase (PASTE / PASSIGE)",
|
|
44
|
+
"recommended": [
|
|
45
|
+
{"assay": "GUIDE-seq / CHANGE-seq", "setting": "nuclease (nickase) off-target", "doi": "10.1038/nbt.3117",
|
|
46
|
+
"use": "confirm the Cas9-nickase off-targets of the pegRNA spacer"},
|
|
47
|
+
{"assay": "Cryptic-seq / HIDE-seq", "setting": "integrase off-target", "doi": "10.1101/2024.08.23.609471",
|
|
48
|
+
"use": "confirm the integrase pseudo-attP sites of the installed att"}],
|
|
49
|
+
"strategy": "PASTE off-target is composite — run BOTH a nuclease assay (for the nickase) AND an "
|
|
50
|
+
"integrase assay (for the installed att); the two components are independent.",
|
|
51
|
+
"available": True,
|
|
52
|
+
"note": "two independent off-target mechanisms; neither assay alone clears a PASTE design."}
|
|
53
|
+
if "cast" in fam or "cas12k" in fam or "shcast" in fam or "vchcast" in fam or "evocast" in fam:
|
|
54
|
+
return {"family": writer_family, "writer_class": "CRISPR-associated transposase (CAST)",
|
|
55
|
+
"recommended": [{"assay": "transposon insertion-site sequencing", "setting": "unbiased integration mapping",
|
|
56
|
+
"doi": "10.1126/science.aax9181",
|
|
57
|
+
"use": "map genome-wide integration sites, including guide-INDEPENDENT untargeted "
|
|
58
|
+
"transposition (the dominant off-target mode for Type V-K, e.g. ShCAST)"}],
|
|
59
|
+
"strategy": "sequence integration sites to capture BOTH guide-directed off-targets and the "
|
|
60
|
+
"guide-independent untargeted-transposition background (Type V-K high; Type I-F low)",
|
|
61
|
+
"available": True,
|
|
62
|
+
"note": "KNOWN GAP: no genome-wide unbiased CELLULAR off-target assay is standardised for human-cell "
|
|
63
|
+
"CAST; untargeted-transposition rates are characterised in bacteria/biochemically. "
|
|
64
|
+
"Mechanism-based, unvalidated."}
|
|
42
65
|
if "bridge" in fam or "is110" in fam or "is621" in fam or "seek" in fam or "iscro4" in fam:
|
|
43
66
|
return {"family": writer_family, "writer_class": "bridge recombinase (IS110/IS621 RNA-guided)",
|
|
44
67
|
"recommended": [{"assay": "targeted amplicon / capture sequencing at nominated pseudosites",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Bridge-recombinase (IS110 / IS621) off-target path (PEN-OFFTGT v2, O-WS4).
|
|
2
|
+
|
|
3
|
+
Bridge recombinases are RNA-guided: the bridge RNA's target-binding loop base-pairs with a bipartite ~14-nt
|
|
4
|
+
genomic target (central CT). Off-target = genomic sites matching that target with tolerated mismatches. This
|
|
5
|
+
wraps the existing genome-wide scanner (`pen_stack.bridge.offtarget`), which seeds on the central core and scores
|
|
6
|
+
each pseudosite by the **measured Perry-2025 DMS specificity landscape** (which target mismatches the recombinase
|
|
7
|
+
tolerates) — a held-out ranking AUROC of 0.88 on that in-vitro DMS data.
|
|
8
|
+
|
|
9
|
+
**Status: mechanism_based_unvalidated (hard-locked).** Crucially, the DMS ranker being validated on *in-vitro
|
|
10
|
+
specificity* does NOT make the *genomic off-target predictions* validated: there is **no published genome-wide
|
|
11
|
+
unbiased CELLULAR off-target assay** for bridge recombinases (the technology is ~2024), so the genomic pseudosite
|
|
12
|
+
calls cannot be validated. The honest report is: a mechanism-based scan with a DMS-grounded mismatch-tolerance
|
|
13
|
+
model, labelled unvalidated, with the no-genome-wide-assay disclosure. Confirm by targeted amplicon /
|
|
14
|
+
integration-site sequencing. Never claims validation.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
_STATUS = "mechanism_based_unvalidated"
|
|
19
|
+
_DISCLOSURE = (
|
|
20
|
+
"NO published genome-wide unbiased CELLULAR off-target assay exists for bridge recombinases (IS110/IS621; the "
|
|
21
|
+
"technology is ~2024). The pseudosite RANKER is validated on the measured Perry-2025 in-vitro DMS specificity "
|
|
22
|
+
"landscape (held-out ranking AUROC 0.88), but genomic recovery is NOT validated. Treat nominations as "
|
|
23
|
+
"high-uncertainty, mechanism-based candidates — never a clearance."
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def nominate_bridge(target_core: str | None = None, writer_family: str = "bridge_IS110",
|
|
28
|
+
fasta=None, chroms: list[str] | None = None, top: int = 20) -> dict:
|
|
29
|
+
"""Genome-wide bridge off-target scan for a bridge-RNA target core, via the DMS-scored engine. Returns the
|
|
30
|
+
ranked pseudosites when a genome + target core are supplied (VM), else reports the engine is ready and how to
|
|
31
|
+
run the scan. Always carries the hard-locked unvalidated status + the no-genome-wide-assay disclosure."""
|
|
32
|
+
from pen_stack.bridge.offtarget import predict_offtargets
|
|
33
|
+
fam = "seek_IS1111" if ("seek" in (writer_family or "").lower() or "is1111" in (writer_family or "").lower()) \
|
|
34
|
+
else "bridge_IS110"
|
|
35
|
+
res = predict_offtargets(fam, target_core=target_core, fasta=fasta, chroms=chroms, top=top)
|
|
36
|
+
return {"family": "bridge", "writer_family": fam, "status": _STATUS,
|
|
37
|
+
"ranker": "Perry-2025 DMS specificity landscape (measured; held-out ranking AUROC 0.88)",
|
|
38
|
+
"no_ground_truth_disclosure": _DISCLOSURE,
|
|
39
|
+
"confirm_assay": "targeted amplicon / integration-site sequencing at nominated pseudosites",
|
|
40
|
+
"available": res.get("status") == "scanned",
|
|
41
|
+
"abstain": not (res.get("status") == "scanned"),
|
|
42
|
+
"engine": res,
|
|
43
|
+
"method": ("seed on the central core (CT), verify the bipartite ~14-nt target with tolerated "
|
|
44
|
+
"mismatches, score by the measured DMS specificity (position + substitution identity)"),
|
|
45
|
+
"honesty": ("mechanism-based CANDIDATES with a DMS-grounded mismatch-tolerance model; NOT a validated "
|
|
46
|
+
"genome-wide predictor (no cellular assay exists) and NOT a clearance."),
|
|
47
|
+
"nomination_is_not_clearance": True}
|