pen-stack 7.1.2__tar.gz → 7.1.3__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.2 → pen_stack-7.1.3}/CHANGELOG.md +46 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/CITATION.cff +2 -2
- {pen_stack-7.1.2 → pen_stack-7.1.3}/PKG-INFO +17 -14
- {pen_stack-7.1.2 → pen_stack-7.1.3}/README.md +16 -13
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/safety/hazard_registry.yaml +63 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/__init__.py +1 -1
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/design/generate.py +14 -3
- pen_stack-7.1.3/pen_stack/design/space.py +136 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/registry.py +68 -3
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/screen.py +2 -1
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/server/api.py +22 -3
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/PKG-INFO +17 -14
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pyproject.toml +1 -1
- pen_stack-7.1.2/pen_stack/design/space.py +0 -85
- {pen_stack-7.1.2 → pen_stack-7.1.3}/LICENSE +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/MANIFEST.in +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/bench/run.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_grounding/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_grounding/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_headtohead/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_routing/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_routing/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_safety/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/chat_safety/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/delivery/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_challenge/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/loop/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/offtarget/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/oracle/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/position_effect/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/position_effect/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/verify/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/writer_efficiency/README.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/benchmarks/writespec/SHA256SUMS +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/aav_serotype_tropism.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/antipeg.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/atlas_families.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/calibration/preexisting_nab_independent.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/cargo_polish.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/cell_types.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/datasets.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/delivery_rules.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/expression/modifiers.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/expression/promoters.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/gates_v3.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/genotoxicity_oracle.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/intent_weights.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/known_unknowns.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/llm.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/metric_guide.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/mhc_epitope_oracle.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/monitor_queries.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/oracles/execution.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/oracles/reliability.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/oracles/scope_cards.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/rules/delivery.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/rules/fold.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/rules/payload.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/rules/reachability.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/safety/policy.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/safety/probes.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/score_axes.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/seroprevalence.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/target_sites.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/write_types.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/writer_sequences.fasta +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/BACKLOG.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/DEPLOY.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/INFRA.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/MCP.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/RELEASING.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/REPRO.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/STABILITY.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/agent.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/autonomy.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/benchmark_circularity.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/biosecurity.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/build_interface.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/atlas.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/durability.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/offtarget_data.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/position_effect_data.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/safety.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/cards/writer_efficiency_data.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/challenge.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/closed_loop.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/co_scientist.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/co_scientist_loop.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/delivery.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/delivery_immunology.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/delivery_recommender.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/digital_twin.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/dissemination.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/environment.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/experiment_design.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/generative_design.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/immune_profiler.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/index.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/integrations.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/live_oracles.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/offtarget.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/oracle_mesh.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/oracles.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/position_effect.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/positioning.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/private_data_formats.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/quickstart.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/responsible_use.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/rule_spec.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/rules.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/scope.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/scorecard.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/tpe_bench.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/uncertainty.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/verify.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/verify_service.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/world_model.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/writer_efficiency.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/writer_verification.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/writespec_bench.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/writespec_profile.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/docs/wtkb.md +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/_resources.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/acquire.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/brains.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/campaign.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/design.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/active/validate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/adapt/report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/cite.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/epistemic.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/mcp_server.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/orchestrator.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/orchestrator_live.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/scope.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/agent/tools.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/api/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/api/manifest.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/crosslink.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/guide_design.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/writer_efficiency.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/writer_predict.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/writer_recommend.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/build/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/build/cloudlab.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/build/ingest.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/build/protocol.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/build/simlab.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/cli.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/encode.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/genome.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/ingest_safety_annot.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/design/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/design/capsid_generate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/design/pareto.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/design/writer_variants.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/env/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/env/policies.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/build.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/query.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/graph/schema.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/loop/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/loop/continual.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/loop/cycle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/loop/drift.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/monitor/run.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/affinity.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/reliability.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/schema.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/status.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/structure.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/structure_run.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/oracles/vcell.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/ada_risk.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/antipeg_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery_immune.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery_predict.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/genotoxicity_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/immune_mhc2.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/immune_profile.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/optimize.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/pipeline.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/router.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/corpus.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/embed.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/ground.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/index.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/llm.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/qa.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rag/retrieve.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/evaluators.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/loader.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/schema.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/solver.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/rules/spec.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/audit.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/gate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/policy.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/redteam.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/safety/standards.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/score/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/server/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/clarify.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/extract.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/cell.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/chem.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/feature.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/gene.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/locus.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/resolvers/phenotype.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/satisfy.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/service.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/spec/writespec.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/calibrate.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/data/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/data/position_effect.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/mechanistic.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/outcome.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/twin/position_effect.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/ui/app.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/closed_loop.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/experiment_design.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/expr_controls.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/generative_design.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/heldout_celltype_expr.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/immune_calibration.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/known_biology_expr.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/outcome_prediction.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/paper3_benchmark.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/protocol_safety.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/safety_screening.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/verify/proof.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/verify/schema.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/verify/service.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/guide.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/llm.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/llm_provider.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/router.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/server.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/web/tools.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/offtarget_assay.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/offtarget_data.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/offtarget_predict.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/SOURCES.txt +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/requires.txt +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_acq.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_calib.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_chat.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_closedloop.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_continual.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_drift.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_gen.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_loop.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_mech.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_oracle.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_orch.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_peg.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_penchat.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_policy.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_profile.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_proto.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_screen.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_verify.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_writer.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_writespec.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/paper1.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/paper2.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/paper3.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/paper4.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/phase0.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_a.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_acq.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_aldesign.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_alvalidate.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_b.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ba.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_bench.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_c.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_cal.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_calib.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_challenge.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_chat.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_cite.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_closedloop.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_continual.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_cosci2.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_crit.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ct.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_d.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_delivery.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_drift.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_e.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_env.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ep.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_expr2.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_f.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_frontend.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_g.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_gen.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_graph.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_h.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_hybrid.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_immune.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_immune2.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_ingest.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_innate.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_loop.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_manifest.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_mc.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_mcp.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_mech.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_mon.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_o.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_offtarget.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_openapi.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_oracle.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_orch.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_outcome.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_pareto.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_peg.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_penchat.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_plan.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_policy.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_profile.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_proto.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_r.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_redteam.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_route.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_screen.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_simlab.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_twincal.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_uq.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_v.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_vcell.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_verify.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_writer.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_writespec.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/prereg/ws_wv.yaml +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/build_capsid_fitness.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/build_rag_corpus.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/calibrate_immune_axes.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/fetch_licensed_sources.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/offtarget_chromatin_incremental.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/offtarget_chromatin_matched.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/offtarget_chromatin_validation.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_build_durability.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_build_position_effect.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_build_writer_eff.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_train_safety.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p1_validation_report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p52_build_genotox_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/ws_b_report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/scripts/ws_c_report.py +0 -0
- {pen_stack-7.1.2 → pen_stack-7.1.3}/setup.cfg +0 -0
|
@@ -3,6 +3,52 @@
|
|
|
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.1.3] - 2026-06-26 - Designer correctness: Guardian biosecurity + calibrated confidence
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- **CRITICAL (Designer / Guardian biosecurity):** Hazardous cargo functions (e.g. furin-cleavage viral
|
|
10
|
+
tropism-enhancement, dominant-negative tumor-suppressor ablation) passed the Designer as "Safety: Clear" with
|
|
11
|
+
full survivor tables. Several root causes, all fixed:
|
|
12
|
+
- The hazard registry (`configs/safety/hazard_registry.yaml`) had **no signatures** for engineered viral tropism
|
|
13
|
+
enhancement or oncogenic tumor-suppressor ablation. Added `FUNC-VIRAL-TROPISM-ENHANCE` (furin cleavage /
|
|
14
|
+
receptor-binding / tropism, high severity) and `FUNC-ONCOGENIC-SUPPRESSOR` (dominant-negative TP53 / RB / PTEN,
|
|
15
|
+
apoptosis-checkpoint ablation, high severity), both DURC / HHS-P3CO categories.
|
|
16
|
+
- **Oncogenic-manipulation PATTERN screen** (`oncogenic_manipulation` in the registry +
|
|
17
|
+
`HazardRegistry.oncogenic_flags`): a flat keyword list is brittle to paraphrase — a red-team pass found the
|
|
18
|
+
Guardian caught only **1/8** mechanism/synonym phrasings ("R175H p53 abolishing transactivation", "PTEN
|
|
19
|
+
knockout", "RAS G12D constitutive activation", "hTERT immortalization", "APC frameshift", "EGFR
|
|
20
|
+
ligand-independent activation", "NF1+BAX/BAK knockout"). The pattern screen flags the *combination*
|
|
21
|
+
`(tumor-suppressor + disruptive verb)` OR `(oncogene + activating signature)` OR `immortalization`, which
|
|
22
|
+
catches **8/8** while the deliberate asymmetry spares therapy with **no allow-list** — restoring a suppressor or
|
|
23
|
+
silencing an oncogene matches neither, so "p53 correction to restore apoptosis", "TRAC/CCR5 knockout",
|
|
24
|
+
"knock-down of mutant KRAS" stay clear (**11/11** benign). Disposition is escalate (dual-use → human review).
|
|
25
|
+
- **Keyword matcher hardened** (`_kw_match`): a plain substring test made the ricin abbreviation `"rip"` fire
|
|
26
|
+
inside **"transc-rip-tion"** (a word in almost every editing design → benign cassettes false-refused as ricin),
|
|
27
|
+
and let a hyphenated `"furin-cleavage"` slip past the space-form keyword. Matching is now separator-insensitive
|
|
28
|
+
(`-`/`_`/space unified) and word-boundary anchored, fixing both the false positive and the evasion.
|
|
29
|
+
- The goal-based candidate path (`pen_stack/design/space.py::candidate_space`) **dropped** the goal's
|
|
30
|
+
`cargo_function`, so the Guardian in `verify()` screened nothing. It is now propagated onto every swept
|
|
31
|
+
candidate. The `/generate` endpoint additionally screens the goal's cargo function FIRST and returns an explicit
|
|
32
|
+
biosecurity refusal (`refused: true` + the safety verdict) so an empty table is correctly attributed to a
|
|
33
|
+
refusal, not a silent "no candidates".
|
|
34
|
+
- **CRITICAL (Designer / calibration):** Confidence was a constant `1.00 · [0.56, 0.71]` for every input because the
|
|
35
|
+
page hardcoded fake planner scores (0.7 / 0.6 / 0.5) on each candidate. The page now submits the design GOAL and
|
|
36
|
+
the engine plans real writable sites with grounded per-locus safety / durability / writer-activity, so the
|
|
37
|
+
confidence band is genuinely calibrated (it differs by locus/vehicle, e.g. F9 → `[0.866, 0.972]`, and is absent
|
|
38
|
+
for a refused design). `web/src/pages/Designer.jsx` rewritten to send a goal and render the refused / empty /
|
|
39
|
+
survivor states distinctly.
|
|
40
|
+
- **Designer (cell types without a measured atlas):** a goal in a cell type with no writability atlas (cd8_t /
|
|
41
|
+
pbmc / h1_hesc / ipsc) returned an empty table, because the planner-backed `candidate_space` needs `plan_write`.
|
|
42
|
+
`generate_designs` now falls back to `space.vehicle_sweep(goal)`: it sweeps the capacity-compatible vehicles,
|
|
43
|
+
carries `cargo_function` (the Guardian still screens), runs full legality + biosecurity discrimination, and
|
|
44
|
+
ABSTAINS on the calibrated confidence (no fabricated band) — surfaced as "abstained, no measured atlas for this
|
|
45
|
+
cell type". `candidate_space` still returns `[]` without the atlas; `generate_designs(candidates=[])` still
|
|
46
|
+
returns `[]`.
|
|
47
|
+
- **Designer (administration context):** the vehicle sweep now filters by the goal's `in_vivo` flag using the
|
|
48
|
+
curated `in_vivo` / `ex_vivo` route flags in `configs/delivery_vehicles.yaml` (an ex-vivo goal keeps
|
|
49
|
+
lentivirus / electroporation / eVLP; an in-vivo goal keeps AAV / LNP / HDAd / HSV / eVLP). Grounded from the
|
|
50
|
+
curated palette, not a clinical claim; `in_vivo=None` keeps all (existing callers/tests unchanged).
|
|
51
|
+
|
|
6
52
|
## [7.1.2] - 2026-06-25 - PEN-CHAT: chat-response latency fix
|
|
7
53
|
|
|
8
54
|
### Fixed
|
|
@@ -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-06-
|
|
4
|
+
version: 7.1.3
|
|
5
|
+
date-released: 2026-06-26
|
|
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: 7.1.
|
|
3
|
+
Version: 7.1.3
|
|
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
|
|
@@ -162,9 +162,10 @@ flowchart TB
|
|
|
162
162
|
| Generative designer | `pen_stack.design` | Proposes candidate writing systems and keeps only those that pass safety, legality, and calibration, returning a Pareto frontier. |
|
|
163
163
|
| Digital twin | `pen_stack.twin` | Calibrated, out-of-distribution-gated outcome prediction, bounded at phenotype. |
|
|
164
164
|
| Experiment designer | `pen_stack.active` | Active learning by expected information gain, with a retrospective active-versus-random evaluation. |
|
|
165
|
-
| Build interface | `pen_stack.build` | Safety-gated protocol export (draft only, never auto-run) and gated ingestion of results. |
|
|
166
|
-
| Closed loop | `pen_stack.loop` | A gated design, build, test, learn loop with drift detection and versioned, reversible recalibration. |
|
|
167
|
-
|
|
|
165
|
+
| Build interface | `pen_stack.build` | Safety-gated protocol export (draft only, never auto-run) and gated ingestion of results, with a cloud-lab connector that runs the biosecurity gate before any submission. |
|
|
166
|
+
| Closed loop | `pen_stack.loop`, `pen_stack.active` | A gated design, build, test, learn loop with drift detection and versioned, reversible recalibration; an SDL-brain benchmark and a validation-campaign engine that orders the most-informative next measurements by expected information gain. |
|
|
167
|
+
| Write intent (WriteSpec) | `pen_stack.spec` | A typed, ontology-backed `WriteRequest` (an SBOL3 profile) with a grounded extractor that resolves free text to verified ontology ids, asks clarifying questions on ambiguity, and runs a SAT feasibility check. |
|
|
168
|
+
| Agent, co-scientist, and chat | `pen_stack.agent`, `pen_stack.web`, `pen_stack.rag` | Goal to cited, auditable plan; MCP server; the co-scientist that drives the loop; and the grounded conversational chat (four lanes: design, explain, meta, general; provenance-tagged retrieval; a swappable LLM provider). |
|
|
168
169
|
| Bridge off-target engine | `pen_stack.bridge` | Off-target nomination and guide QC for bridge recombinases. |
|
|
169
170
|
| Interfaces | `pen_stack.server`, `pen_stack.web`, `pen_stack.ui`, `pen_stack.cli` | REST API, web application, and command-line tools. |
|
|
170
171
|
|
|
@@ -249,20 +250,22 @@ A single assembly path (`pen_stack/atlas/universe.py`) feeds the classifier, the
|
|
|
249
250
|
```
|
|
250
251
|
pen-stack/
|
|
251
252
|
pen_stack/ the installable package
|
|
252
|
-
|
|
253
|
-
|
|
253
|
+
spec/ WriteSpec: typed SBOL3-profile intent layer, grounded extractor, ontology resolvers, SAT feasibility
|
|
254
|
+
wgenome/ Writable Genome: features, safety, durability, writability, uncertainty, structure3d, off-target nomination
|
|
255
|
+
atlas/ Writer Atlas, knowledge base, cross-link, variant proposal, canonical universe, writer-efficiency predictor
|
|
254
256
|
mech/ score/ mechanism classification at scale; re-grounded therapeutic-readiness axes
|
|
255
|
-
planner/ Write Planner: optimisation, cargo, routing, delivery palette, delivery immunology
|
|
257
|
+
planner/ Write Planner: optimisation, cargo, routing, delivery palette, delivery immunology, capsid fitness
|
|
256
258
|
bridge/ bridge off-target engine and guide QC
|
|
257
|
-
oracles/ oracle mesh: the OracleResult contract and adapters over the foundation models
|
|
259
|
+
oracles/ oracle mesh: the OracleResult contract and adapters over the foundation models, with binding-affinity and per-oracle reliability
|
|
258
260
|
graph/ living world-model knowledge graph (gated, propose-only)
|
|
259
|
-
rules/ verify/ machine-readable rule base
|
|
260
|
-
safety/ the biosecurity and dual-use gate
|
|
261
|
-
design/ twin/ generative designer; calibrated digital twin
|
|
262
|
-
active/ build/ experiment designer; safety-gated build interface
|
|
261
|
+
rules/ verify/ machine-readable rule base, the verify(design) service, and the proof-object with repair hints
|
|
262
|
+
safety/ the biosecurity and dual-use gate, with standards concordance
|
|
263
|
+
design/ twin/ generative designer; calibrated digital twin with a learned position-effect model
|
|
264
|
+
active/ build/ experiment designer with the SDL-brain benchmark and validation-campaign engine; safety-gated build interface and cloud-lab connector
|
|
263
265
|
loop/ the gated design-build-test-learn loop
|
|
266
|
+
rag/ PEN-CHAT: provenance-tagged retrieval corpus, embedder, and four-branch ground router (social, cited, general, abstained)
|
|
264
267
|
agent/ agent platform, co-scientist, MCP server
|
|
265
|
-
api/ web/ server/ ui/ cli.py AI integration surface, web platform, REST API, CLI
|
|
268
|
+
api/ web/ server/ ui/ cli.py AI integration surface, web platform with the grounded chat and swappable LLM provider, REST API, CLI
|
|
266
269
|
benchmarks/ Genome-Writing Bench and the public Genome-Writing Challenge
|
|
267
270
|
scripts/ reproducible pipeline drivers
|
|
268
271
|
configs/ pinned datasets, thresholds, and curation (YAML)
|
|
@@ -296,7 +299,7 @@ All public: hg38 (UCSC); ENCODE and Roadmap chromatin (ATAC/DNase and histone ma
|
|
|
296
299
|
author = {Mahaboob Ali, Anees Ahmed},
|
|
297
300
|
title = {PEN-STACK: open infrastructure for genome writing (The Writable Genome)},
|
|
298
301
|
year = {2026},
|
|
299
|
-
version = {
|
|
302
|
+
version = {7.1.2},
|
|
300
303
|
url = {https://github.com/ahmedanees-m/pen-stack}
|
|
301
304
|
}
|
|
302
305
|
```
|
|
@@ -85,9 +85,10 @@ flowchart TB
|
|
|
85
85
|
| Generative designer | `pen_stack.design` | Proposes candidate writing systems and keeps only those that pass safety, legality, and calibration, returning a Pareto frontier. |
|
|
86
86
|
| Digital twin | `pen_stack.twin` | Calibrated, out-of-distribution-gated outcome prediction, bounded at phenotype. |
|
|
87
87
|
| Experiment designer | `pen_stack.active` | Active learning by expected information gain, with a retrospective active-versus-random evaluation. |
|
|
88
|
-
| Build interface | `pen_stack.build` | Safety-gated protocol export (draft only, never auto-run) and gated ingestion of results. |
|
|
89
|
-
| Closed loop | `pen_stack.loop` | A gated design, build, test, learn loop with drift detection and versioned, reversible recalibration. |
|
|
90
|
-
|
|
|
88
|
+
| Build interface | `pen_stack.build` | Safety-gated protocol export (draft only, never auto-run) and gated ingestion of results, with a cloud-lab connector that runs the biosecurity gate before any submission. |
|
|
89
|
+
| Closed loop | `pen_stack.loop`, `pen_stack.active` | A gated design, build, test, learn loop with drift detection and versioned, reversible recalibration; an SDL-brain benchmark and a validation-campaign engine that orders the most-informative next measurements by expected information gain. |
|
|
90
|
+
| Write intent (WriteSpec) | `pen_stack.spec` | A typed, ontology-backed `WriteRequest` (an SBOL3 profile) with a grounded extractor that resolves free text to verified ontology ids, asks clarifying questions on ambiguity, and runs a SAT feasibility check. |
|
|
91
|
+
| Agent, co-scientist, and chat | `pen_stack.agent`, `pen_stack.web`, `pen_stack.rag` | Goal to cited, auditable plan; MCP server; the co-scientist that drives the loop; and the grounded conversational chat (four lanes: design, explain, meta, general; provenance-tagged retrieval; a swappable LLM provider). |
|
|
91
92
|
| Bridge off-target engine | `pen_stack.bridge` | Off-target nomination and guide QC for bridge recombinases. |
|
|
92
93
|
| Interfaces | `pen_stack.server`, `pen_stack.web`, `pen_stack.ui`, `pen_stack.cli` | REST API, web application, and command-line tools. |
|
|
93
94
|
|
|
@@ -172,20 +173,22 @@ A single assembly path (`pen_stack/atlas/universe.py`) feeds the classifier, the
|
|
|
172
173
|
```
|
|
173
174
|
pen-stack/
|
|
174
175
|
pen_stack/ the installable package
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
spec/ WriteSpec: typed SBOL3-profile intent layer, grounded extractor, ontology resolvers, SAT feasibility
|
|
177
|
+
wgenome/ Writable Genome: features, safety, durability, writability, uncertainty, structure3d, off-target nomination
|
|
178
|
+
atlas/ Writer Atlas, knowledge base, cross-link, variant proposal, canonical universe, writer-efficiency predictor
|
|
177
179
|
mech/ score/ mechanism classification at scale; re-grounded therapeutic-readiness axes
|
|
178
|
-
planner/ Write Planner: optimisation, cargo, routing, delivery palette, delivery immunology
|
|
180
|
+
planner/ Write Planner: optimisation, cargo, routing, delivery palette, delivery immunology, capsid fitness
|
|
179
181
|
bridge/ bridge off-target engine and guide QC
|
|
180
|
-
oracles/ oracle mesh: the OracleResult contract and adapters over the foundation models
|
|
182
|
+
oracles/ oracle mesh: the OracleResult contract and adapters over the foundation models, with binding-affinity and per-oracle reliability
|
|
181
183
|
graph/ living world-model knowledge graph (gated, propose-only)
|
|
182
|
-
rules/ verify/ machine-readable rule base
|
|
183
|
-
safety/ the biosecurity and dual-use gate
|
|
184
|
-
design/ twin/ generative designer; calibrated digital twin
|
|
185
|
-
active/ build/ experiment designer; safety-gated build interface
|
|
184
|
+
rules/ verify/ machine-readable rule base, the verify(design) service, and the proof-object with repair hints
|
|
185
|
+
safety/ the biosecurity and dual-use gate, with standards concordance
|
|
186
|
+
design/ twin/ generative designer; calibrated digital twin with a learned position-effect model
|
|
187
|
+
active/ build/ experiment designer with the SDL-brain benchmark and validation-campaign engine; safety-gated build interface and cloud-lab connector
|
|
186
188
|
loop/ the gated design-build-test-learn loop
|
|
189
|
+
rag/ PEN-CHAT: provenance-tagged retrieval corpus, embedder, and four-branch ground router (social, cited, general, abstained)
|
|
187
190
|
agent/ agent platform, co-scientist, MCP server
|
|
188
|
-
api/ web/ server/ ui/ cli.py AI integration surface, web platform, REST API, CLI
|
|
191
|
+
api/ web/ server/ ui/ cli.py AI integration surface, web platform with the grounded chat and swappable LLM provider, REST API, CLI
|
|
189
192
|
benchmarks/ Genome-Writing Bench and the public Genome-Writing Challenge
|
|
190
193
|
scripts/ reproducible pipeline drivers
|
|
191
194
|
configs/ pinned datasets, thresholds, and curation (YAML)
|
|
@@ -219,7 +222,7 @@ All public: hg38 (UCSC); ENCODE and Roadmap chromatin (ATAC/DNase and histone ma
|
|
|
219
222
|
author = {Mahaboob Ali, Anees Ahmed},
|
|
220
223
|
title = {PEN-STACK: open infrastructure for genome writing (The Writable Genome)},
|
|
221
224
|
year = {2026},
|
|
222
|
-
version = {
|
|
225
|
+
version = {7.1.2},
|
|
223
226
|
url = {https://github.com/ahmedanees-m/pen-stack}
|
|
224
227
|
}
|
|
225
228
|
```
|
|
@@ -133,6 +133,69 @@ controlled_functions:
|
|
|
133
133
|
keywords: ["pathogen_essential", "virulence_factor", "pathogen essential"]
|
|
134
134
|
control_ref: "DURC policy"
|
|
135
135
|
severity: medium
|
|
136
|
+
- id: FUNC-VIRAL-TROPISM-ENHANCE
|
|
137
|
+
# v7.1.2 CRITICAL: Added to catch furin-cleavage and other viral enhancement modifications.
|
|
138
|
+
# Furin is a ubiquitous human protease; inserting furin cleavage sites increases proteolytic
|
|
139
|
+
# activation of viral glycoproteins, broadening cell tropism and transmissibility (GOF concern).
|
|
140
|
+
name: "engineered enhancement of viral cell tropism / proteolytic activation (furin cleavage, PRRA inserts)"
|
|
141
|
+
keywords: ["furin cleavage", "furin_cleavage", "protease activation", "receptor binding enhancement",
|
|
142
|
+
"tropism enhancement", "tropism_expansion", "virulence enhancement"]
|
|
143
|
+
control_ref: "DURC policy (GOF concern, HHS P3CO oversight)"
|
|
144
|
+
severity: high
|
|
145
|
+
- id: FUNC-ONCOGENIC-SUPPRESSOR
|
|
146
|
+
# v7.1.2 CRITICAL: Added to catch dominant-negative tumor suppressors and oncogenic manipulations.
|
|
147
|
+
# Deleting or inhibiting tumor suppressors (TP53, RB, PTEN) ablates apoptosis/cell-cycle checkpoints,
|
|
148
|
+
# enabling unrestricted proliferation and malignant transformation (oncogenic context).
|
|
149
|
+
name: "dominant-negative / ablation of tumor-suppressor checkpoints (TP53, RB, PTEN, APC)"
|
|
150
|
+
keywords: ["dominant-negative", "dominant negative", "tp53_suppressor", "p53_ablation", "rb_suppressor",
|
|
151
|
+
"pten_suppressor", "apc_suppressor", "apoptosis_checkpoint_ablation", "cell_cycle_checkpoint_ablation",
|
|
152
|
+
"tumor_suppressor_knockout", "unrestricted_proliferation", "apoptosis_evasion"]
|
|
153
|
+
control_ref: "DURC policy (oncogenic context, malignant transformation risk)"
|
|
154
|
+
severity: high
|
|
155
|
+
|
|
156
|
+
# --- Oncogenic-manipulation PATTERN screen (v7.1.2). -----------------------------------
|
|
157
|
+
# A flat keyword list (FUNC-ONCOGENIC-SUPPRESSOR above) catches only literal phrasings; an adversary (or an
|
|
158
|
+
# honest user) describing the same edit by MECHANISM or SYNONYM evades it ("R175H p53 that abolishes
|
|
159
|
+
# transactivation", "PTEN knockout", "RAS G12D constitutive activation", "hTERT immortalization"). This pattern
|
|
160
|
+
# screen flags the COMBINATION rather than a fixed phrase:
|
|
161
|
+
# (tumor-suppressor gene token + a disruptive verb) -> losing a growth/apoptosis brake
|
|
162
|
+
# (oncogene token + an activating signature) -> flooring a growth accelerator
|
|
163
|
+
# (an immortalization signature) -> bypassing replicative senescence
|
|
164
|
+
# The asymmetry is deliberate and is what spares legitimate therapy WITHOUT an explicit allow-list: RESTORING a
|
|
165
|
+
# suppressor or SILENCING/knocking-down an oncogene does not match (restoration verbs are not disruptive; silencing
|
|
166
|
+
# is not an activating signature), so "wild-type p53 correction to restore apoptosis" or "knock down mutant KRAS"
|
|
167
|
+
# stay clear. Disposition is ESCALATE (medium): deliberate oncogenic transformation is dual-use, but cancer-model
|
|
168
|
+
# research is legitimate and has an IBC/oversight path, so it routes to human review rather than a blanket refuse;
|
|
169
|
+
# the blatant dominant-negative phrasings still REFUSE via FUNC-ONCOGENIC-SUPPRESSOR. Tokens are public gene
|
|
170
|
+
# symbols / standard molecular-biology verbs - no exploit detail.
|
|
171
|
+
oncogenic_manipulation:
|
|
172
|
+
id: FUNC-ONCOGENIC-PATTERN
|
|
173
|
+
name: "engineered oncogenic transformation (tumor-suppressor disruption / oncogene activation / immortalization)"
|
|
174
|
+
control_ref: "DURC policy (oncogenic transformation); cancer-model research has a legitimate IBC/oversight path"
|
|
175
|
+
severity: medium
|
|
176
|
+
tumor_suppressors: ["tp53", "trp53", " p53", "rb1", "retinoblastoma protein", "pten", " apc ", "cdkn2a",
|
|
177
|
+
"ink4a", " p16", " arf ", " nf1", "neurofibromin", "brca1", "brca2", " vhl", "smad4",
|
|
178
|
+
"stk11", " lkb1", " bax", " bak", "pro-apoptotic", "tumor suppressor", "tumour suppressor"]
|
|
179
|
+
oncogenes: ["kras", "nras", "hras", "k-ras", "n-ras", "h-ras", " ras ", " myc", "c-myc", "mycn", "braf",
|
|
180
|
+
"egfr", "erbb2", " her2", "pik3ca", " akt ", " alk ", " met ", " ret ", "bcr-abl", "ccnd1",
|
|
181
|
+
"cyclin d", " mdm2", "ezh2", "beta-catenin", "wnt-target", "mapk flux", "pi3k/akt"]
|
|
182
|
+
disrupt_verbs: ["knockout", "knock out", "knock-out", "knocked out", "disrupt", "ablat", "dominant-negative",
|
|
183
|
+
"dominant negative", "frameshift", "inactivat", "abolish", "sequester", "loss-of-function",
|
|
184
|
+
"loss of function", "null allele", "truncat", "silence the suppressor", "remove the",
|
|
185
|
+
"release the", "derepress", "lipid-phosphatase brake"]
|
|
186
|
+
activate_signatures: ["constitutive activ", "constitutively active", "gain-of-function", "gain of function",
|
|
187
|
+
"activating mutation", "oncogenic mutation", "ligand-independent", "ligand independent",
|
|
188
|
+
"autoinhibition", "g12d", "g12v", "g12c", "g13d", "q61", "v600e", "gtp-bound active",
|
|
189
|
+
"switch in its gtp", "constitutive mapk", "constitutive wnt", "constitutive signaling",
|
|
190
|
+
"constitutive survival", "hyperactivat", "independent of ligand", "sustain constitutive"]
|
|
191
|
+
immortalization: ["immortaliz", "telomerase", "htert", "unlimited replicative", "unlimited proliferat",
|
|
192
|
+
"unrestricted proliferat", "indefinite proliferat", "replicative lifespan", "bypass senescence",
|
|
193
|
+
"evade senescence", "escape senescence"]
|
|
194
|
+
# restoration verbs that, when no disruptive/activating/immortalization signal is present, keep a suppressor /
|
|
195
|
+
# oncogene mention CLEAR (therapeutic gene correction). Belt-and-braces on top of the asymmetric logic.
|
|
196
|
+
therapy_context: ["restore", "restoration", "correct the", "gene correction", "wild-type replacement",
|
|
197
|
+
"replace the defective", "reconstitute the wild-type", "functional copy", "supplementation",
|
|
198
|
+
"wild-type p53 gene correction"]
|
|
136
199
|
|
|
137
200
|
# --- Chimera / context rules: hazardous ASSEMBLY of individually-benign parts. ---------
|
|
138
201
|
chimera_rules:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""PEN-STACK v3.0 - open infrastructure for genome writing."""
|
|
2
|
-
__version__ = "7.1.
|
|
2
|
+
__version__ = "7.1.3"
|
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
|
-
from pen_stack.design.space import candidate_space
|
|
13
|
+
from pen_stack.design.space import candidate_space, vehicle_sweep
|
|
14
14
|
from pen_stack.verify import verify
|
|
15
15
|
|
|
16
16
|
# a survivor must be legal AND safe (cleared or low-severity advisory); refuse/escalate are discarded.
|
|
@@ -29,8 +29,19 @@ def generate_designs(goal: dict | None = None, *, candidates: list[dict] | None
|
|
|
29
29
|
by confidence. Hazardous (refuse/escalate) or illegal proposals are discarded, never returned.
|
|
30
30
|
|
|
31
31
|
Pass an explicit ``candidates`` list to discriminate a known pool (atlas-independent); otherwise candidates
|
|
32
|
-
are enumerated from ``goal`` via the planner-backed candidate space.
|
|
33
|
-
|
|
32
|
+
are enumerated from ``goal`` via the planner-backed candidate space.
|
|
33
|
+
|
|
34
|
+
v7.1.2: when the goal's cell type has NO measured writability atlas (so the planner-backed candidate_space
|
|
35
|
+
yields nothing), fall back to an atlas-free vehicle sweep so the legality + biosecurity discrimination still
|
|
36
|
+
runs; those survivors carry no calibrated confidence (it abstains honestly, surfaced in the UI) rather than
|
|
37
|
+
the page showing an empty table for a perfectly legal, screened design. The explicit-``candidates`` path is
|
|
38
|
+
untouched (``generate_designs(candidates=[])`` still returns [])."""
|
|
39
|
+
if candidates is not None:
|
|
40
|
+
pool = candidates
|
|
41
|
+
else:
|
|
42
|
+
pool = candidate_space(goal or {}, n=n)
|
|
43
|
+
if not pool and goal: # atlas absent for this cell type -> atlas-free sweep (confidence will abstain)
|
|
44
|
+
pool = vehicle_sweep(goal, n=n)
|
|
34
45
|
survivors: list[dict] = []
|
|
35
46
|
for d in pool:
|
|
36
47
|
v = verify(dict(d), actor=actor)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Candidate-space generation for the generative designer (v5.8, WS-GEN support).
|
|
2
|
+
|
|
3
|
+
`candidate_space(goal)` enumerates candidate end-to-end writing systems, writer x site x cargo x delivery,
|
|
4
|
+
by wrapping the validated Phase-3 inverse-design planner (`plan_write`) for the site x writer x scores, then
|
|
5
|
+
pairing each with every *compatible* delivery vehicle from the curated palette (cargo fits the vehicle
|
|
6
|
+
capacity). Every candidate carries the planner's grounded scores (safety / p_durable / writer_activity) so the
|
|
7
|
+
verifier-as-discriminator can compute a calibrated confidence and the v5.6 immune profile downstream.
|
|
8
|
+
|
|
9
|
+
Atlas-dependent: when the Phase-1 writability atlas is absent (e.g. a bare laptop checkout), `plan_write`
|
|
10
|
+
yields nothing and `candidate_space` returns []. The discriminator/Pareto logic is independent of the atlas and
|
|
11
|
+
is exercised on explicit candidates (tests/bench fixtures); the atlas path runs on the VM/with data.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from pen_stack.planner.delivery_vehicles import names as _vehicle_names
|
|
18
|
+
from pen_stack.planner.delivery_vehicles import vehicle as _vehicle
|
|
19
|
+
|
|
20
|
+
# edit-intent -> write_type (the router/verifier dispatches on write_type)
|
|
21
|
+
_INTENT_WRITE_TYPE = {
|
|
22
|
+
"safe_harbour_insertion": "insertion",
|
|
23
|
+
"high_durability_insertion": "insertion",
|
|
24
|
+
"knock_in_with_disruption": "insertion",
|
|
25
|
+
"landing_pad_insertion": "landing_pad",
|
|
26
|
+
"regulatory_element_excision": "excision",
|
|
27
|
+
"repeat_excision": "excision",
|
|
28
|
+
"regulatory_rewrite": "regulatory_rewrite",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _compatible_vehicles(cargo_bp: int, in_vivo: bool | None = None) -> list[str]:
|
|
33
|
+
"""Vehicles whose curated cargo capacity fits the cargo (capacity None = no DNA-packaging limit).
|
|
34
|
+
|
|
35
|
+
v7.1.2: when an administration ``in_vivo`` context is given, also filter by the vehicle's curated route
|
|
36
|
+
(the `in_vivo` / `ex_vivo` flags in configs/delivery_vehicles.yaml) - an in-vivo goal keeps the in-vivo-capable
|
|
37
|
+
vehicles, an ex-vivo goal keeps the ex-vivo-capable ones (e.g. lentivirus / electroporation / eVLP). This is a
|
|
38
|
+
grounded compatibility filter from the curated palette, not a clinical claim. ``in_vivo=None`` keeps all."""
|
|
39
|
+
out = []
|
|
40
|
+
for n in _vehicle_names():
|
|
41
|
+
v = _vehicle(n) or {}
|
|
42
|
+
cap = v.get("cargo_capacity_bp")
|
|
43
|
+
if cap is not None and cargo_bp > cap:
|
|
44
|
+
continue
|
|
45
|
+
if in_vivo is True and not v.get("in_vivo"):
|
|
46
|
+
continue
|
|
47
|
+
if in_vivo is False and not v.get("ex_vivo"):
|
|
48
|
+
continue
|
|
49
|
+
out.append(n)
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def deliverability_score(vehicle_name: str, cargo_bp: int) -> float:
|
|
54
|
+
"""Grounded deliverability proxy: capacity headroom (more spare capacity = more deliverable),
|
|
55
|
+
clipped to [0,1]. Vehicles with no packaging limit score 1.0. NOT a clinical claim."""
|
|
56
|
+
cap = (_vehicle(vehicle_name) or {}).get("cargo_capacity_bp")
|
|
57
|
+
if cap is None:
|
|
58
|
+
return 1.0
|
|
59
|
+
if cargo_bp > cap:
|
|
60
|
+
return 0.0
|
|
61
|
+
return max(0.0, min(1.0, (cap - cargo_bp) / cap))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def candidate_space(goal: dict, *, n: int = 200, k: int = 8) -> list[dict[str, Any]]:
|
|
65
|
+
"""Enumerate candidate designs for a goal {gene, intent, cargo_bp, cell_type, cargo_function?}. Each candidate
|
|
66
|
+
is a plain dict consumable by `verify()` and carries the planner's grounded scores. Returns [] if the atlas is
|
|
67
|
+
absent.
|
|
68
|
+
|
|
69
|
+
v7.1.2: the goal's screening-relevant fields (cargo_function, cargo_seq, in_vivo, delivery_tropism,
|
|
70
|
+
replication_competent) are PROPAGATED onto every candidate so the Guardian biosecurity gate in verify() screens
|
|
71
|
+
the cargo function for each swept vehicle. Previously these were dropped here, so a hazardous cargo function
|
|
72
|
+
reached NO screen on the goal-based path."""
|
|
73
|
+
gene = goal["gene"]
|
|
74
|
+
intent = goal.get("intent") or goal.get("edit_intent") or "safe_harbour_insertion"
|
|
75
|
+
cargo_bp = int(goal.get("cargo_bp") or goal.get("payload_bp") or 3000)
|
|
76
|
+
ct = goal.get("cell_type") or goal.get("ct") or "k562"
|
|
77
|
+
write_type = _INTENT_WRITE_TYPE.get(intent, "insertion")
|
|
78
|
+
# screening-relevant goal fields propagated onto every candidate (the Guardian reads cargo_function).
|
|
79
|
+
screen_extra = {f: goal[f] for f in ("cargo_function", "cargo_seq", "in_vivo", "delivery_tropism",
|
|
80
|
+
"replication_competent") if goal.get(f) is not None}
|
|
81
|
+
|
|
82
|
+
from pen_stack.planner.pipeline import plan_write
|
|
83
|
+
try:
|
|
84
|
+
plans = plan_write(gene, intent, cargo_bp, ct, k=k)
|
|
85
|
+
except Exception: # atlas/data absent -> no candidates (discriminator/Pareto unaffected)
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
vehicles = _compatible_vehicles(cargo_bp, in_vivo=goal.get("in_vivo"))
|
|
89
|
+
cands: list[dict] = []
|
|
90
|
+
for p in plans:
|
|
91
|
+
for veh in vehicles:
|
|
92
|
+
cands.append({
|
|
93
|
+
**screen_extra, # v7.1.2: cargo_function et al. so the Guardian screens this candidate
|
|
94
|
+
"write_type": write_type, "gene": gene, "chrom": p["site"]["chrom"],
|
|
95
|
+
"edit_intent": intent, "writer_family": p["writer"], "cargo_bp": cargo_bp,
|
|
96
|
+
"cell_type": ct, "delivery_vehicle": veh,
|
|
97
|
+
# grounded planner scores (model_extra) -> verify() calibrated confidence + downstream:
|
|
98
|
+
"safety": p["safety"], "p_durable": p["durability"], "writer_activity": p["writer_activity"],
|
|
99
|
+
"on_target": p["on_target"], "reachability_tier": p.get("reachability_tier"),
|
|
100
|
+
"deliverability": deliverability_score(veh, cargo_bp),
|
|
101
|
+
"_planner_score": p["score"],
|
|
102
|
+
"provenance": {**p.get("provenance", {}), "candidate_space": "v5.8 plan_write x delivery palette"},
|
|
103
|
+
})
|
|
104
|
+
if len(cands) >= n:
|
|
105
|
+
return cands
|
|
106
|
+
return cands
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def vehicle_sweep(goal: dict, *, n: int = 200) -> list[dict[str, Any]]:
|
|
110
|
+
"""Atlas-FREE candidate enumeration: sweep the compatible delivery vehicles for the goal WITHOUT planner
|
|
111
|
+
scores. Used when the writability atlas has no coverage for the requested cell type (e.g. cd8_t / pbmc /
|
|
112
|
+
h1_hesc), so `candidate_space` (which needs `plan_write`) yields nothing.
|
|
113
|
+
|
|
114
|
+
Each candidate carries the goal's cargo_function (so the Guardian still screens it), the cargo size (so the
|
|
115
|
+
capacity rules still filter oversize vehicles), and NO safety/p_durable/writer_activity (so verify() honestly
|
|
116
|
+
ABSTAINS on the calibrated confidence rather than inventing one). The legality + biosecurity discrimination is
|
|
117
|
+
fully exercised; only the calibrated-confidence column is left uncomputed (and labelled as such in the UI)."""
|
|
118
|
+
intent = goal.get("intent") or goal.get("edit_intent") or "safe_harbour_insertion"
|
|
119
|
+
cargo_bp = int(goal.get("cargo_bp") or goal.get("payload_bp") or 3000)
|
|
120
|
+
ct = goal.get("cell_type") or goal.get("ct") or "k562"
|
|
121
|
+
write_type = _INTENT_WRITE_TYPE.get(intent, "insertion")
|
|
122
|
+
screen_extra = {f: goal[f] for f in ("cargo_function", "cargo_seq", "in_vivo", "delivery_tropism",
|
|
123
|
+
"replication_competent") if goal.get(f) is not None}
|
|
124
|
+
cands: list[dict] = []
|
|
125
|
+
for veh in _compatible_vehicles(cargo_bp, in_vivo=goal.get("in_vivo")):
|
|
126
|
+
cands.append({
|
|
127
|
+
**screen_extra,
|
|
128
|
+
"write_type": write_type, "gene": goal.get("gene"), "chrom": goal.get("chrom"),
|
|
129
|
+
"edit_intent": intent, "cargo_bp": cargo_bp, "cell_type": ct, "delivery_vehicle": veh,
|
|
130
|
+
"deliverability": deliverability_score(veh, cargo_bp),
|
|
131
|
+
"provenance": {"candidate_space": "v7.1.2 atlas-free vehicle sweep "
|
|
132
|
+
"(no measured writability atlas for this cell type; confidence abstains)"},
|
|
133
|
+
})
|
|
134
|
+
if len(cands) >= n:
|
|
135
|
+
break
|
|
136
|
+
return cands
|
|
@@ -12,6 +12,7 @@ sequence still carries a hazardous FUNCTION annotation, and function, not homolo
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
import re
|
|
15
16
|
from dataclasses import dataclass, field
|
|
16
17
|
from typing import Any, Callable
|
|
17
18
|
|
|
@@ -27,6 +28,26 @@ def _norm(s: Any) -> str:
|
|
|
27
28
|
return str(s or "").strip().lower()
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
def _sep_norm(s: Any) -> str:
|
|
32
|
+
"""Lowercase and collapse separator runs (whitespace / hyphen / underscore) to a single space, so
|
|
33
|
+
"furin-cleavage", "furin_cleavage" and "furin cleavage" are one token. Keeps the matcher robust to the
|
|
34
|
+
hyphen/space/underscore variation that is ubiquitous in free-text function descriptions."""
|
|
35
|
+
return re.sub(r"[\s_\-]+", " ", _norm(s)).strip()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _kw_match(kw: str, text: str) -> bool:
|
|
39
|
+
"""Separator-insensitive, word-boundary keyword match (v7.1.2). Two failure modes of a plain substring test:
|
|
40
|
+
(1) over-broad - the short ricin keyword "rip" matches inside "transc-RIP-tion", a word in almost every
|
|
41
|
+
genome-editing design, so a benign promoter cassette would false-refuse as ricin; (2) too-narrow - a
|
|
42
|
+
hyphenated "furin-cleavage" would slip past the space-form keyword "furin cleavage". Normalising separators
|
|
43
|
+
then matching on alphanumeric boundaries fixes both: "rip" matches "RIP" standalone but not inside a longer
|
|
44
|
+
word, and "furin cleavage" / "furin-cleavage" / "furin_cleavage" all match."""
|
|
45
|
+
k = _sep_norm(kw)
|
|
46
|
+
if not k:
|
|
47
|
+
return False
|
|
48
|
+
return re.search(r"(?<![a-z0-9])" + re.escape(k) + r"(?![a-z0-9])", _sep_norm(text)) is not None
|
|
49
|
+
|
|
50
|
+
|
|
30
51
|
def _design_function_tokens(design: dict) -> set[str]:
|
|
31
52
|
"""Normalised function annotations declared on a design (NOT free-text justification)."""
|
|
32
53
|
toks: set[str] = set()
|
|
@@ -57,6 +78,7 @@ class HazardRegistry:
|
|
|
57
78
|
regulated_taxa: list[dict] = field(default_factory=list)
|
|
58
79
|
controlled_functions: list[dict] = field(default_factory=list)
|
|
59
80
|
chimera_rules: list[dict] = field(default_factory=list)
|
|
81
|
+
oncogenic_manipulation: dict = field(default_factory=dict)
|
|
60
82
|
external_enabled: bool = False
|
|
61
83
|
external_hook: Callable[[str], list[ScreenHit]] | None = None
|
|
62
84
|
|
|
@@ -71,6 +93,7 @@ class HazardRegistry:
|
|
|
71
93
|
regulated_taxa=raw.get("regulated_taxa", []),
|
|
72
94
|
controlled_functions=raw.get("controlled_functions", []),
|
|
73
95
|
chimera_rules=raw.get("chimera_rules", []),
|
|
96
|
+
oncogenic_manipulation=raw.get("oncogenic_manipulation", {}),
|
|
74
97
|
external_enabled=external_hook is not None,
|
|
75
98
|
external_hook=external_hook,
|
|
76
99
|
)
|
|
@@ -88,7 +111,7 @@ class HazardRegistry:
|
|
|
88
111
|
pfam = _design_pfam(design)
|
|
89
112
|
for entry in self.toxin_functions + self.controlled_functions:
|
|
90
113
|
by_pfam = pfam & {_norm(p) for p in entry.get("pfam", [])}
|
|
91
|
-
by_kw = {kw for kw in (entry.get("keywords") or []) if any(
|
|
114
|
+
by_kw = {kw for kw in (entry.get("keywords") or []) if any(_kw_match(kw, t) for t in toks)}
|
|
92
115
|
if by_pfam or by_kw:
|
|
93
116
|
ev = {}
|
|
94
117
|
if by_pfam:
|
|
@@ -100,6 +123,47 @@ class HazardRegistry:
|
|
|
100
123
|
provenance=self._prov(entry), evidence=ev))
|
|
101
124
|
return hits
|
|
102
125
|
|
|
126
|
+
def oncogenic_flags(self, design: dict) -> list[ScreenHit]:
|
|
127
|
+
"""Oncogenic-manipulation PATTERN screen (v7.1.2). Flags the COMBINATION that a flat keyword list misses:
|
|
128
|
+
a tumor-suppressor gene with a disruptive verb, an oncogene with an activating signature, or an
|
|
129
|
+
immortalization signature. The asymmetry spares therapy without an allow-list (restoring a suppressor /
|
|
130
|
+
silencing an oncogene matches neither). Escalates to human review (dual-use, legitimate cancer-model path)."""
|
|
131
|
+
cfg = self.oncogenic_manipulation
|
|
132
|
+
if not cfg:
|
|
133
|
+
return []
|
|
134
|
+
# screen the declared function annotations only (the artifact, not any free-text justification)
|
|
135
|
+
text = " " + " | ".join(sorted(_design_function_tokens(design))) + " "
|
|
136
|
+
if not text.strip(" |"):
|
|
137
|
+
return []
|
|
138
|
+
|
|
139
|
+
def has(keys: list[str]) -> list[str]:
|
|
140
|
+
return [k for k in (keys or []) if _norm(k) in text]
|
|
141
|
+
|
|
142
|
+
supp = has(cfg.get("tumor_suppressors"))
|
|
143
|
+
onco = has(cfg.get("oncogenes"))
|
|
144
|
+
disrupt = has(cfg.get("disrupt_verbs"))
|
|
145
|
+
activate = has(cfg.get("activate_signatures"))
|
|
146
|
+
immortal = has(cfg.get("immortalization"))
|
|
147
|
+
therapy = has(cfg.get("therapy_context"))
|
|
148
|
+
|
|
149
|
+
reasons = []
|
|
150
|
+
if supp and disrupt:
|
|
151
|
+
reasons.append(f"tumor-suppressor disruption ({supp[0]} + {disrupt[0]})")
|
|
152
|
+
if onco and activate:
|
|
153
|
+
reasons.append(f"oncogene activation ({onco[0]} + {activate[0]})")
|
|
154
|
+
if immortal:
|
|
155
|
+
reasons.append(f"immortalization signature ({immortal[0]})")
|
|
156
|
+
if not reasons:
|
|
157
|
+
return []
|
|
158
|
+
# therapeutic restoration / supplementation with NO disruptive/activating/immortalization signal -> clear.
|
|
159
|
+
if therapy and not (disrupt or activate or immortal):
|
|
160
|
+
return []
|
|
161
|
+
return [ScreenHit(kind="oncogenic_flag", detail=cfg.get("name", "oncogenic manipulation"),
|
|
162
|
+
severity=cfg.get("severity", "medium"), provenance=self._prov(cfg),
|
|
163
|
+
evidence={"patterns": reasons,
|
|
164
|
+
"suppressor": supp[:2], "oncogene": onco[:2], "disrupt": disrupt[:2],
|
|
165
|
+
"activate": activate[:2], "immortalization": immortal[:2]})]
|
|
166
|
+
|
|
103
167
|
def taxon_flags(self, design: dict) -> list[ScreenHit]:
|
|
104
168
|
"""Regulated-pathogen-TAXON screen (Select Agent / Australia Group membership by declared source)."""
|
|
105
169
|
hits: list[ScreenHit] = []
|
|
@@ -121,8 +185,9 @@ class HazardRegistry:
|
|
|
121
185
|
hits: list[ScreenHit] = []
|
|
122
186
|
rules = {r["id"]: r for r in self.chimera_rules}
|
|
123
187
|
|
|
124
|
-
|
|
125
|
-
|
|
188
|
+
cf = _norm(design.get("cargo_function"))
|
|
189
|
+
has_toxin = bool(self.function_flags(design)) or bool(cf) and any(
|
|
190
|
+
_kw_match(kw, cf) for e in self.toxin_functions for kw in (e.get("keywords") or []))
|
|
126
191
|
broad = _norm(design.get("delivery_tropism")) in {"broad", "broad_systemic", "systemic"} or \
|
|
127
192
|
_norm(design.get("delivery_vehicle")) in {"aav9", "aavrh10"}
|
|
128
193
|
replicating = bool(design.get("replication_competent"))
|
|
@@ -15,7 +15,7 @@ from typing import Literal
|
|
|
15
15
|
|
|
16
16
|
from pydantic import BaseModel, Field
|
|
17
17
|
|
|
18
|
-
ScreenKind = Literal["sequence_homology", "function_flag", "taxon_flag", "chimera_context"]
|
|
18
|
+
ScreenKind = Literal["sequence_homology", "function_flag", "taxon_flag", "chimera_context", "oncogenic_flag"]
|
|
19
19
|
Severity = Literal["low", "medium", "high"]
|
|
20
20
|
|
|
21
21
|
|
|
@@ -43,6 +43,7 @@ def screen_design(design: dict, registry=None) -> list[ScreenHit]:
|
|
|
43
43
|
design = dict(design)
|
|
44
44
|
hits: list[ScreenHit] = []
|
|
45
45
|
hits += reg.function_flags(design) # toxin / pathogen-essential function domains
|
|
46
|
+
hits += reg.oncogenic_flags(design) # v7.1.2 oncogenic-manipulation pattern (mechanism/synonym-robust)
|
|
46
47
|
hits += reg.taxon_flags(design) # regulated pathogen taxa
|
|
47
48
|
hits += reg.chimera_context(design) # hazardous assembly of benign parts
|
|
48
49
|
seq = _assemble_cargo(design)
|
|
@@ -440,11 +440,30 @@ def delivery_tropism_endpoint(target_tissue: str):
|
|
|
440
440
|
@app.post("/generate", tags=["v6.1 AI surface"])
|
|
441
441
|
def generate_endpoint(req: dict):
|
|
442
442
|
"""v5.8 generative designer: verifier-as-discriminator. Body: {goal?, candidates?, keep?}. Hazardous/illegal
|
|
443
|
-
candidates are discarded; survivors are calibrated + immune-profiled candidates (never asserted to work).
|
|
443
|
+
candidates are discarded; survivors are calibrated + immune-profiled candidates (never asserted to work).
|
|
444
|
+
|
|
445
|
+
v7.1.2: the GOAL'S cargo function is screened by the Guardian FIRST, before the vehicle x cargo sweep. A
|
|
446
|
+
hazardous goal (e.g. a furin-cleavage tropism-enhancement or a dominant-negative tumor-suppressor ablation) is
|
|
447
|
+
REFUSED up front and the response carries the explicit safety verdict, so an empty result is correctly
|
|
448
|
+
attributed to a biosecurity refusal (not a silent 'no candidates'). The per-candidate Guardian still runs in
|
|
449
|
+
verify() as defence in depth."""
|
|
444
450
|
from pen_stack.design import generate_designs
|
|
445
|
-
|
|
451
|
+
goal = req.get("goal")
|
|
452
|
+
# Guardian pre-screen on the goal's declared cargo function (the artifact, not any free-text justification).
|
|
453
|
+
if isinstance(goal, dict) and any(goal.get(f) for f in ("cargo_function", "cargo_seq")):
|
|
454
|
+
from pen_stack.safety.gate import safety_gate
|
|
455
|
+
screen = {f: goal[f] for f in ("cargo_function", "cargo_seq", "gene", "delivery_vehicle", "in_vivo",
|
|
456
|
+
"delivery_tropism", "replication_competent") if goal.get(f) is not None}
|
|
457
|
+
gv = safety_gate(screen, actor=str(req.get("actor", "api")))
|
|
458
|
+
if gv.decision in ("refuse", "escalate"):
|
|
459
|
+
return {"survivors": [], "refused": True,
|
|
460
|
+
"safety": {"decision": gv.decision, "reason": gv.reason,
|
|
461
|
+
"hits": [{"detail": h.detail, "severity": h.severity, "kind": h.kind}
|
|
462
|
+
for h in gv.hits]},
|
|
463
|
+
"disclaimer": _DISCLAIMER}
|
|
464
|
+
return {"survivors": generate_designs(goal, candidates=req.get("candidates"),
|
|
446
465
|
keep=int(req.get("keep", 25)), actor=str(req.get("actor", "api"))),
|
|
447
|
-
"disclaimer": _DISCLAIMER}
|
|
466
|
+
"refused": False, "disclaimer": _DISCLAIMER}
|
|
448
467
|
|
|
449
468
|
|
|
450
469
|
@app.post("/predict", tags=["v6.1 AI surface"])
|