pen-stack 7.2.3__tar.gz → 8.0.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.2.3 → pen_stack-8.0.1}/CHANGELOG.md +481 -34
- {pen_stack-7.2.3 → pen_stack-8.0.1}/CITATION.cff +7 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/PKG-INFO +130 -58
- pen_stack-8.0.1/README.md +295 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/bench/run.py +14 -5
- pen_stack-8.0.1/benchmarks/agentic_baseline/README.md +47 -0
- pen_stack-8.0.1/benchmarks/genome_writing_bench/SHA256SUMS +7 -0
- pen_stack-8.0.1/benchmarks/genotox_panel/README.md +107 -0
- pen_stack-8.0.1/benchmarks/grounding_llm_on/README.md +58 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/integrase/README.md +6 -6
- pen_stack-8.0.1/benchmarks/offtarget/integrase_chalberg/README.md +61 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/position_effect/README.md +11 -3
- pen_stack-8.0.1/benchmarks/position_effect_human/README.md +119 -0
- pen_stack-8.0.1/benchmarks/position_effect_human/SHA256SUMS +3 -0
- pen_stack-8.0.1/benchmarks/priorart/epridict/README.md +62 -0
- pen_stack-8.0.1/benchmarks/priorart/epridict/SHA256SUMS +5 -0
- pen_stack-8.0.1/benchmarks/priorart/gsh_recovery/README.md +66 -0
- pen_stack-8.0.1/benchmarks/priorart/gsh_recovery/SHA256SUMS +4 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/intent_weights.yaml +16 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/llm.yaml +13 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/cast_systems.yaml +6 -6
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/integrase_att.yaml +7 -7
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/INFRA.md +1 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/biosecurity.md +41 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/offtarget_data.md +4 -4
- pen_stack-8.0.1/docs/cards/priorart.md +66 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/responsible_use.md +14 -2
- pen_stack-8.0.1/pen_stack/__init__.py +2 -0
- pen_stack-8.0.1/pen_stack/active/acquire.py +165 -0
- pen_stack-8.0.1/pen_stack/active/design.py +66 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/epistemic.py +6 -4
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/orchestrator.py +7 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/api/manifest.py +2 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/crosslink.py +34 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/guide_design.py +5 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_recommend.py +65 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/generate.py +12 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/space.py +1 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/writer_variants.py +4 -3
- pen_stack-8.0.1/pen_stack/graph/query.py +148 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/schema.py +16 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/structure.py +1 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_immune.py +2 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_predict.py +73 -13
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/immune_profile.py +24 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/optimize.py +31 -4
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/pipeline.py +1 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/llm.py +37 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/evaluators.py +21 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/schema.py +20 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/gate.py +21 -0
- pen_stack-8.0.1/pen_stack/safety/pfam_scan.py +157 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/policy.py +5 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/registry.py +17 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/screen.py +10 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/server/api.py +106 -25
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/extract.py +26 -4
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/data/position_effect.py +29 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/mechanistic.py +17 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/outcome.py +31 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/position_effect.py +81 -7
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper3_benchmark.py +2 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/proof.py +31 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/schema.py +6 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/service.py +4 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_assay.py +3 -1
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_bridge.py +2 -2
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_cast.py +5 -5
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_enumerate.py +6 -6
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_integrase.py +34 -8
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_nuclease.py +35 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_paste.py +3 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_predict.py +6 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/PKG-INFO +130 -58
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/SOURCES.txt +19 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/requires.txt +9 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_offtarget2.json +1 -1
- pen_stack-8.0.1/prereg/SHA256_LOCK_ws_priorart.json +10 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_offtarget2.yaml +3 -3
- pen_stack-8.0.1/prereg/ws_priorart.yaml +169 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pyproject.toml +9 -3
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/build_capsid_fitness.py +5 -0
- pen_stack-8.0.1/scripts/fetch_artifacts.sh +215 -0
- pen_stack-8.0.1/scripts/p2_build_human_head.py +79 -0
- pen_stack-8.0.1/scripts/pa_epridict_distinctness.py +66 -0
- pen_stack-8.0.1/scripts/reproduce.py +115 -0
- pen_stack-8.0.1/scripts/validate_components.py +158 -0
- pen_stack-7.2.3/README.md +0 -232
- pen_stack-7.2.3/benchmarks/genome_writing_bench/SHA256SUMS +0 -7
- pen_stack-7.2.3/pen_stack/__init__.py +0 -2
- pen_stack-7.2.3/pen_stack/active/acquire.py +0 -73
- pen_stack-7.2.3/pen_stack/active/design.py +0 -51
- pen_stack-7.2.3/pen_stack/graph/query.py +0 -79
- {pen_stack-7.2.3 → pen_stack-8.0.1}/LICENSE +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/MANIFEST.in +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_grounding/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_grounding/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_headtohead/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_routing/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_routing/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_safety/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_safety/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/delivery/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_challenge/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/loop/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/integrase/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/oracle/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/position_effect/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/verify/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writer_efficiency/README.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writespec/SHA256SUMS +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/aav_serotype_tropism.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/antipeg.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/atlas_families.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/calibration/preexisting_nab_independent.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/cargo_polish.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/cell_types.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/datasets.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_rules.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/expression/modifiers.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/expression/promoters.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/gates_v3.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/genotoxicity_oracle.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/known_unknowns.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/metric_guide.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/mhc_epitope_oracle.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/monitor_queries.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/execution.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/reliability.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/scope_cards.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/compliance.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/delivery.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/fold.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/payload.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/reachability.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/hazard_registry.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/policy.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/probes.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/score_axes.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/seroprevalence.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/target_sites.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/write_types.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/writer_sequences.fasta +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/offtarget/enumerated_cache.parquet +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/data/offtarget/motif_cache.parquet +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/BACKLOG.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/DEPLOY.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/MCP.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/RELEASING.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/REPRO.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/STABILITY.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/agent.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/autonomy.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/benchmark_circularity.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/build_interface.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/atlas.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/durability.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/position_effect_data.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/safety.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/writer_efficiency_data.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/challenge.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/closed_loop.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/co_scientist.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/co_scientist_loop.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery_immunology.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery_recommender.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/digital_twin.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/dissemination.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/environment.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/experiment_design.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/generative_design.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/immune_profiler.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/index.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/integrations.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/live_oracles.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/offtarget.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/oracle_mesh.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/oracles.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/position_effect.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/positioning.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/private_data_formats.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/quickstart.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/rule_spec.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/rules.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/scope.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/scorecard.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tpe_bench.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/uncertainty.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/verify.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/verify_service.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/world_model.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writer_efficiency.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writer_verification.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writespec_bench.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writespec_profile.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/wtkb.md +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/_resources.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/brains.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/campaign.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/validate.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/cite.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/mcp_server.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/orchestrator_live.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/scope.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/tools.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/api/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_efficiency.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_predict.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/cloudlab.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/ingest.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/protocol.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/simlab.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/cli.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/encode.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/genome.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_safety_annot.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/capsid_generate.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/pareto.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/policies.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/build.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/schema.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/continual.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/cycle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/drift.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/run.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/affinity.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/reliability.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/status.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/structure_run.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/vcell.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/ada_risk.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/antipeg_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/chromosome.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/genotoxicity_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/immune_mhc2.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/router.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/corpus.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/embed.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/ground.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/index.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/qa.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/retrieve.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/loader.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/solver.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/spec.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/audit.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/redteam.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/standards.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/server/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/clarify.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/cell.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/chem.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/feature.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/gene.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/locus.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/phenotype.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/satisfy.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/service.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/writespec.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/calibrate.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/data/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/ui/app.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/closed_loop.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/experiment_design.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/expr_controls.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/generative_design.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/heldout_celltype_expr.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/immune_calibration.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/known_biology_expr.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/outcome_prediction.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/protocol_safety.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/safety_screening.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/guide.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/llm.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/llm_provider.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/router.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/server.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/tools.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_data.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_acq.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_calib.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_chat.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_closedloop.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_continual.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_drift.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_gen.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_loop.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mech.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_oracle.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_orch.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_peg.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_penchat.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_policy.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_profile.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_proto.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_screen.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_verify.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_writer.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_writespec.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper1.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper2.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper3.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper4.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/phase0.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_a.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_acq.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_aldesign.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_alvalidate.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_b.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_bench.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_c.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cal.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_calib.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_challenge.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_chat.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cite.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_closedloop.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_continual.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cosci2.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_crit.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ct.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_d.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_delivery.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_drift.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_e.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_env.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ep.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_expr2.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_f.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_frontend.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_g.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_gen.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_graph.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_h.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_hybrid.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_immune.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_immune2.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ingest.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_innate.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_loop.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_manifest.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mc.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mcp.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mech.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mon.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_o.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_offtarget.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_openapi.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_oracle.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_orch.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_outcome.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_pareto.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_peg.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_penchat.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_plan.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_policy.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_profile.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_proto.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_r.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_redteam.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_route.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_screen.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_simlab.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_twincal.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_uq.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_v.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_vcell.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_verify.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_writer.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_writespec.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_wv.yaml +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/build_rag_corpus.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/calibrate_immune_axes.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/fetch_licensed_sources.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_incremental.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_matched.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_validation.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_durability.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_position_effect.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_writer_eff.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_train_safety.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_validation_report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p52_build_genotox_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/ws_b_report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/ws_c_report.py +0 -0
- {pen_stack-7.2.3 → pen_stack-8.0.1}/setup.cfg +0 -0
|
@@ -3,13 +3,460 @@
|
|
|
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
|
+
## [8.0.1] - 2026-07-13
|
|
7
|
+
|
|
8
|
+
A reproducibility and API-hardening patch. No scientific result and no public function signature changes.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Result, verdict, and safety types are now immutable (frozen).** `OracleResult` and its nested
|
|
12
|
+
`Provenance`, `Verdict`, `SafetyVerdict`, `ScreenHit`, `Rule`, and `RuleResult` can no longer be mutated
|
|
13
|
+
after construction, so a result's provenance and scope, a verdict's legality, or a screen hit's severity
|
|
14
|
+
cannot be edited downstream. Build a changed copy with `model_copy(update=...)`.
|
|
15
|
+
- **The REST, MCP, and Gymnasium-environment tests and the SBOL3/GenBank round-trip run by default.**
|
|
16
|
+
`fastapi`, `uvicorn`, `httpx`, `fastmcp`, `gymnasium`, `sbol3`, and `biopython` are in the `[dev]` extra, so
|
|
17
|
+
the full suite exercises these features rather than skipping them. Heavy compiled extras stay opt-in.
|
|
18
|
+
- **The one-command reproduction recomputes a second headline from committed source.**
|
|
19
|
+
`scripts/pa_epridict_distinctness.py` (wired into `make repro`) re-derives the durability-vs-ePRIDICT
|
|
20
|
+
distinctness result, and `scripts/reproduce.py` now distinguishes recomputed headlines from echoed sealed
|
|
21
|
+
metrics.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- **An abstention is no longer reported as high confidence.** A design verified with no calibrated confidence
|
|
25
|
+
is now `not-computable`, not `grounded-confident`.
|
|
26
|
+
- **The frozen-input integrity check works on a fresh checkout.** `python bench/run.py --verify` parses the
|
|
27
|
+
standard `sha256sum` manifest format (two-space, CRLF-tolerant); the manifest re-seals only on explicit
|
|
28
|
+
`--seal`; a `.gitattributes` pins the hashed inputs to LF for cross-platform stability.
|
|
29
|
+
- **The reproduction harness can fail.** `scripts/reproduce.py` exits non-zero if any block fails instead of
|
|
30
|
+
always reporting success.
|
|
31
|
+
- Corrected the ePRIDICT variance figure in the README (R-squared 0.041, matching the committed metrics).
|
|
32
|
+
|
|
33
|
+
## [8.0.0] - 2026-07-13 - Stable release of record
|
|
34
|
+
|
|
35
|
+
The first stable, citable release. The major version marks a committed public API surface (the SDK
|
|
36
|
+
functions, the REST endpoints, and the twenty MCP tools) governed by a one-minor-version deprecation policy.
|
|
37
|
+
It consolidates the gated 7.x development trail rather than replacing it: the pre-registrations, SHA-locked
|
|
38
|
+
benchmarks, and disclosed negatives that trail documents remain intact and referenced. Stable surfaces
|
|
39
|
+
carry calibrated uncertainty and validation status; the mechanism-based paths (serine-integrase, bridge, and
|
|
40
|
+
CAST off-target) are marked experimental and may change.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **A one-chromosome demo atlas** (`data/demo/atlas_k562.parquet`, chr19). A fresh clone can run the
|
|
44
|
+
safe-harbour quickstart without first fetching the full release: `PEN_ATLAS_DIR=data/demo pen-stack
|
|
45
|
+
writable --gene AAVS1 --ct k562` returns the ranked writable bins of the AAVS1 (PPP1R12C) locus. Opt-in via
|
|
46
|
+
`PEN_ATLAS_DIR`, so the atlas-gated test suite is unchanged. Full genome-wide atlases come from Zenodo via
|
|
47
|
+
`scripts/fetch_artifacts.sh`.
|
|
48
|
+
- **An Anthropic (Claude) provider in the LLM layer.** `pen_stack/rag/llm.py` now supports three provider
|
|
49
|
+
styles (OpenAI-compatible, Ollama, Anthropic Messages), including multi-turn tool calling, so the
|
|
50
|
+
conversational agent and the evaluations run provider-agnostically across hosted-frontier and local models.
|
|
51
|
+
Keys are read from an env var or a gitignored file and are never committed.
|
|
52
|
+
- **A measured, LLM-on grounding evaluation** (`benchmarks/grounding_llm_on/`). The ungrounded-baseline
|
|
53
|
+
contrast ships a committed metrics file and an adversarial probe set, run with the model live across three
|
|
54
|
+
model families: with no tools an ungrounded model emits concrete tool-only quantities (fabrication), while
|
|
55
|
+
the grounded agent, which routes every quantity through a validated tool, emits none. Transcripts are cached
|
|
56
|
+
and replay offline in CI.
|
|
57
|
+
- **An agentic baseline** (`benchmarks/agentic_baseline/`). A real external LLM agent drives the validated
|
|
58
|
+
tools and every number in its trace is audited to a direct tool call. Verified across three models spanning
|
|
59
|
+
a small local model to hosted-frontier models; the no-fabrication audit passes for all.
|
|
60
|
+
- **A one-command reproduction path.** `make repro` reproduces every result that runs on the committed data
|
|
61
|
+
and the demo atlas on a fresh clone, with no download and no API key (`scripts/reproduce.py`); `make fetch`
|
|
62
|
+
then `make repro-full` add the genome-wide atlas benchmarks from the Zenodo release. Verified end to end in
|
|
63
|
+
a clean `python:3.12-slim` container.
|
|
64
|
+
- **Committed metrics for the three headline analyses** (`benchmarks/position_effect_human/`,
|
|
65
|
+
`offtarget/integrase_chalberg/`, `genotox_panel/`), so the paper's central numbers reproduce directly from
|
|
66
|
+
the repository.
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
- Benchmark provenance references relative paths only. The license (MIT), MCP tool count (twenty), and
|
|
70
|
+
Verify-Bench rule count (eleven) are reconciled across the package metadata, the repository, and the
|
|
71
|
+
manuscript. The repository was confirmed free of hardcoded credentials, addresses, and absolute local paths.
|
|
72
|
+
|
|
73
|
+
## [7.3.21] - 2026-07-11 - World-model graph: resolve any locus (not just exact GSH names)
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
- **The world-model graph query resolved only the exact curated safe-harbour node names.** The graph materialises
|
|
77
|
+
a `locus:` node for each curated GSH locus and matched the query string exactly, so `PPP1R12C` (AAVS1's anchor
|
|
78
|
+
gene), `ROSA26` (whose node is `hRosa26`), and real genes such as TRAC, HBB, and LMO2 all returned nothing. The
|
|
79
|
+
query now resolves in three tiers:
|
|
80
|
+
- A curated node is matched by **GSH name, anchor gene, or alias, case-insensitively** (AAVS1 ≡ aavs1 ≡
|
|
81
|
+
PPP1R12C; ROSA26 ≡ hRosa26; HIPP11 ≡ H11), returning the same DOI-provenanced answer.
|
|
82
|
+
- A query that is not a curated safe harbour but resolves to a **real gene** returns the **tier-1 reprogrammable
|
|
83
|
+
writers**, which engage any locus at the locus level (the documented crosslink property), flagged as a
|
|
84
|
+
candidate rather than a curated safe harbour (per-site reachability and safety remain the Planner's and
|
|
85
|
+
Guardian's responsibility).
|
|
86
|
+
- Anything else returns an explained empty result rather than an error.
|
|
87
|
+
The response carries `resolved_locus` and `is_curated_safe_harbour`, and the Closed Loop page shows the resolved
|
|
88
|
+
locus and a curated-vs-candidate badge.
|
|
89
|
+
|
|
90
|
+
## [7.3.20] - 2026-07-11 - Stage J closed loop: a UI surface + /cloudlab 500-on-bad-provider fix
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
- **`POST /api/cloudlab` returned an unhandled 500 for any `provider` other than "mock".** `submit()` raises
|
|
94
|
+
`CloudLabError` for a provider outside the wired set, but `submit_gated()` caught only the safety refusal
|
|
95
|
+
(`ProtocolExportError`), so it propagated. The endpoint now returns a **422** with the valid-provider list for an
|
|
96
|
+
unknown provider, and a null/empty/missing provider falls back to the wired `mock` dry-run path.
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
- **A "Closed Loop" page (Stage J).** Three closed-loop capabilities previously reachable only via the API are now
|
|
100
|
+
surfaced (the fourth, the validation campaign, is already on Experiments):
|
|
101
|
+
- **Build & submit (cloud-lab)**: a design form plus provider select drives the verify-first flow: a cleared
|
|
102
|
+
design returns a DRAFT protocol preview and a mock/dry-run job receipt (Level 3, human-in-control); a hazardous
|
|
103
|
+
cargo (e.g. ricin) is refused with no protocol emitted.
|
|
104
|
+
- **SDL-brain benchmark**: the EIG/VOI designer versus random/greedy (curve-area gap with CI), BayBE/Atlas
|
|
105
|
+
cited, with a "BayBE not installed in this deployment" note when the optional dependency is absent.
|
|
106
|
+
- **World-model graph**: a locus/cargo-form query returns the provenanced writer→locus→vehicle paths.
|
|
107
|
+
Wired into the left-rail nav (Build & learn) and the router at `/closed-loop`.
|
|
108
|
+
|
|
109
|
+
## [7.3.19] - 2026-07-11 - Experiment designer: expected information gain varies with cell-type coverage
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
- **`expected_info_gain` now varies across candidates** instead of reducing to the twin's fixed ±0.20 uncertainty
|
|
113
|
+
band (which read a near-constant ~0.0202 for every candidate). EIG folds in the design-varying uncertainty the
|
|
114
|
+
fixed band understates: an unmeasured cell type (no atlas data, so more reducible uncertainty) and an
|
|
115
|
+
out-of-distribution design widen the effective standard deviation. EIG is ~0.02 in a fully-measured cell
|
|
116
|
+
(K562/HepG2), ~0.43 partially-measured (HSPC), ~0.71 unmeasured (iPSC/PBMC/…), and ~1.5 out-of-distribution; it
|
|
117
|
+
is constant across gene/vehicle/cargo within one cell type, since the mechanistic twin carries no per-gene
|
|
118
|
+
uncertainty. Coverage and OOD are folded into EIG rather than double-counted as separate acquisition terms.
|
|
119
|
+
|
|
120
|
+
## [7.3.18] - 2026-07-11 - Experiment designer: acquisition rebuilt on design-varying signals
|
|
121
|
+
|
|
122
|
+
### Changed
|
|
123
|
+
- **The experiment-suggestion acquisition is rebuilt on design-varying signals.** Expected information gain derives
|
|
124
|
+
entirely from the twin's fixed ±0.20 uncertainty band, so the suggested batch scored a near-constant ~0.02 for
|
|
125
|
+
almost every candidate, and the pool varied only vehicle × cargo at one cell type, where relative expression is
|
|
126
|
+
per-copy (cargo-independent). The acquisition now combines:
|
|
127
|
+
- **Coverage novelty**: an experiment in an unmeasured cell type reduces more uncertainty; the measured-atlas
|
|
128
|
+
roster (K562/HepG2 full, HSPC partial, others none) drives it.
|
|
129
|
+
- **Feasibility gate**: an experiment that cannot be built as specified (cargo overflowing the vehicle) is
|
|
130
|
+
down-weighted.
|
|
131
|
+
- **Immune value-of-information**, counting only **in-scope** proxy axes, so it varies by vehicle (a PEGylated
|
|
132
|
+
LNP puts the anti-PEG axis in scope; AAV does not).
|
|
133
|
+
- **Marginal gain**: the submodular greedy objective (informativeness minus overlap with the picks already
|
|
134
|
+
scheduled), distinct per experiment and decreasing down the batch.
|
|
135
|
+
The candidate pool spans all cell types × 4 vehicles so the coverage/feasibility/immune signals differ across it;
|
|
136
|
+
the batch is scored per candidate cell, and each experiment is returned with its full breakdown. The Experiments
|
|
137
|
+
page shows the marginal-gain ranking with a "why" line (coverage, immune-VOI, buildability) and states that the
|
|
138
|
+
mechanistic twin cannot finely rank two experiments in the same regime, the ranking is coverage + buildability +
|
|
139
|
+
immune-VOI + diversity. `select_batch` scores each candidate once.
|
|
140
|
+
- The "Load expression-validation campaign" plan is a fixed pre-registered 48-row campaign, independent of the
|
|
141
|
+
candidate-pool form; the scores panel notes this.
|
|
142
|
+
|
|
143
|
+
## [7.3.17] - 2026-07-10 - App-wide input-validation sweep (out-of-domain values are flagged everywhere)
|
|
144
|
+
|
|
145
|
+
### Added
|
|
146
|
+
- **A consistent input-validation pass across every page.** Shared helpers in `lib/format.js`
|
|
147
|
+
(`invalidNucleotides`, `clampInt`) and a reusable `SeqWarning` component in `ui.jsx`:
|
|
148
|
+
- **Nucleotide sequence fields** warn on characters outside A/C/G/T/U/N (kept, not silently accepted):
|
|
149
|
+
Design Studio / Twin / Guardian cargo sequence, Off-Target guide / crRNA spacer / bridge target-core, Writer
|
|
150
|
+
Atlas guide-design target and donor.
|
|
151
|
+
- **Writer Atlas "Cargo bp"** now shows the same "clamped to X (allowed 1–300,000)" note Site Finder uses,
|
|
152
|
+
instead of clamping silently.
|
|
153
|
+
- **Design Studio multiplex edits**: the free-text chromosome flags an invalid value (chr1–chr22, chrX/Y/M)
|
|
154
|
+
and the genomic position clamps to a non-negative coordinate (was `parseInt || 0`, accepting negatives).
|
|
155
|
+
- Twin chromatin marks (0–1) and cargo-size vehicle cap + non-positive (from 7.3.16) complete the set.
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
- **Twin chromatin-mark fields no longer mangle a typed negative** (`"-5"` had become `"05"`). The value was
|
|
159
|
+
coerced with `parseFloat || 0` on every keystroke, collapsing a lone leading `-` to `0`. The fields now hold
|
|
160
|
+
the raw string while editing (coerced to a number only at predict time) and drop the native `min`/`max`, so an
|
|
161
|
+
out-of-range value, including a negative, can be entered and is flagged rather than silently blocked.
|
|
162
|
+
Free-text NL fields (co-scientist chat, WriteSpec brief), amino-acid / SMILES fields (capsid, oracles), and the
|
|
163
|
+
free-form model-feature fields are intentionally left unconstrained, since client-side validation would false-warn.
|
|
164
|
+
|
|
165
|
+
## [7.3.16] - 2026-07-10 - Stage-H: vehicle-aware cargo hint, OOD-widen scope, input range warnings
|
|
166
|
+
|
|
167
|
+
### Fixed
|
|
168
|
+
- **The "Cargo size (bp)" hint reflects the selected delivery vehicle.** It was hardcoded to "AAV single-vector
|
|
169
|
+
payload caps near ~4.7 kb" for every vehicle; it now reflects the selected vehicle's real capacity (AAV dual
|
|
170
|
+
~9 kb, lentivirus ~8 kb, LNP ~15 kb, HDAd ~35 kb, HSV ~100 kb, electroporation = no packaging limit), sourced
|
|
171
|
+
from a `VEHICLE_CAP_BP` map mirroring `configs/delivery_vehicles.yaml`, with an inline over-capacity warning when
|
|
172
|
+
the entered cargo exceeds the cap.
|
|
173
|
+
- **The Stage-H "OOD widen" factor and its presentation.** The factor reads near its ×3 ceiling for most realistic
|
|
174
|
+
chromatin input. It is genuinely computed (near-zero input ≈ ×1, mid-range ≈ ×2.4–×2.8, cap ×3), but the
|
|
175
|
+
position-effect head was trained on normalized exact-site features, so typical 0–1 histone values at the app's
|
|
176
|
+
coarse 1 kb resolution sit outside that distribution and the widen flags them as out-of-distribution (near the
|
|
177
|
+
cap). The stat caption, the not-outcome-validated banner, and the scores panel now explain that a high widen at
|
|
178
|
+
this resolution is the signal working, the same cause as `outcome_validated: false`, rather than a fixed value.
|
|
179
|
+
|
|
180
|
+
### Added
|
|
181
|
+
- **Range warnings on out-of-domain inputs.** The five chromatin marks are documented normalized signal in [0,1];
|
|
182
|
+
the fields previously accepted e.g. -5 and fed it to the model unflagged. They are now bordered and warned when
|
|
183
|
+
outside 0–1 (value kept, not clamped, so the OOD signal still reflects it). A non-positive cargo size is flagged
|
|
184
|
+
(`feasibility.buildable=False` + `cargo_size_nonpositive` scope flag) instead of reading as buildable.
|
|
185
|
+
- **A promoter/cell-type note.** Selecting a tissue-specific promoter (e.g. TBG = liver) surfaces that the
|
|
186
|
+
mechanistic estimate is cell-type-agnostic and applies the same strength regardless of tissue match, so a
|
|
187
|
+
maximally-optimistic score for a biologically inappropriate promoter/cell-type pairing is not misread.
|
|
188
|
+
|
|
189
|
+
## [7.3.15] - 2026-07-09 - Health check surfaces writability-atlas presence (deploy-mount visibility)
|
|
190
|
+
|
|
191
|
+
### Fixed
|
|
192
|
+
- **`/api/health` reports whether the per-cell-type writability atlases are present,** not just the bundled
|
|
193
|
+
writer atlas. A deploy that drops the runtime `-v ~/data/out:/work/data/out` mount leaves the container with no
|
|
194
|
+
per-cell-type atlas parquets, so Site Finder returns `atlas_<ct>.parquet not found` and the cell-type dropdown
|
|
195
|
+
shows "no atlas" for every cell type (including the measured K562/HepG2/HSPC), yet `/api/health` stayed green
|
|
196
|
+
because `atlas_present` checks only the bundled writer atlas. Health now includes `writability_atlas:
|
|
197
|
+
{measured_count, measured, ok}`; `measured_count == 0` makes a dropped-mount deploy immediately visible.
|
|
198
|
+
|
|
199
|
+
## [7.3.14] - 2026-07-09 - Digital Twin: surface the Stage-H model's OWN OOD signal + disambiguate the two OOD checks
|
|
200
|
+
|
|
201
|
+
### Fixed
|
|
202
|
+
- **The Twin page's top-level "OOD" flag is disambiguated from the Stage-H model's own OOD signal.** The
|
|
203
|
+
top-level flag is bound to the **virtual-cell response oracle's** scope card (its list of in-distribution cell
|
|
204
|
+
types and perturbation kinds), and every cell type the dropdown offers is on that list, so it reads "no" through
|
|
205
|
+
this UI by construction, not a broken gate. The Stage-H **position-effect** model has its own separate
|
|
206
|
+
out-of-distribution signal (`ood_widen`, a Mahalanobis distance over the 5 supplied chromatin marks) that the
|
|
207
|
+
API returned but the UI never surfaced (×2.09 at typical marks, saturating at ×3.0 for marks pushed to 10–100).
|
|
208
|
+
Changes:
|
|
209
|
+
- The Stage-H card shows an **"OOD widen (this head)"** stat (×1 typical → ×3 cap), colour-graded, so the
|
|
210
|
+
position-effect model's own OOD signal is visible and moves with the chromatin context.
|
|
211
|
+
- The top-level stat is relabelled **"OOD (response model)"** with an inline note that it is the response
|
|
212
|
+
oracle's scope-card check (expected to read "no" for any dropdown cell type), a different signal from the
|
|
213
|
+
Stage-H widen factor.
|
|
214
|
+
- The "How to read these scores" panel documents both OOD checks separately.
|
|
215
|
+
- A regression test locks in that `position_effect.ood_widen` widens for out-of-range chromatin marks.
|
|
216
|
+
|
|
217
|
+
## [7.3.13] - 2026-07-09 - Guardian: FASTA-header robustness fix + Design Studio Proof detail parity
|
|
218
|
+
|
|
219
|
+
### Fixed
|
|
220
|
+
- **A sequence pasted straight from a database (a `>accession description` FASTA header plus wrapped sequence
|
|
221
|
+
lines) is now screened correctly.** `_looks_like_nucleotide()` ran on the raw pasted text, header included; the
|
|
222
|
+
header's non-nucleotide characters diluted the nucleotide fraction below the classification threshold, so the
|
|
223
|
+
header+sequence blob was misclassified as protein and scanned as one string, with no 6-frame translation. The
|
|
224
|
+
screen now strips FASTA/GenBank header lines (`>`, `;`) and whitespace before the nucleotide-vs-protein decision
|
|
225
|
+
(`_strip_headers_and_whitespace`) and cleans stray non-amino-acid characters in the protein branch. A
|
|
226
|
+
FASTA-formatted toxin sequence that previously returned zero hits now refuses.
|
|
227
|
+
- **Design Studio's Proof object (`/api/verify/proof`) carries the full hazard detail.** A hazard hit was reduced
|
|
228
|
+
to a bare `{signature, kind, severity}` with no reason, citation, or (for a sequence-domain hit) the Pfam
|
|
229
|
+
accession/bit score that Guardian's `/api/safety` view already showed. `_biosecurity_axis()` now carries `reason`
|
|
230
|
+
(the matched signature name), `citation` (the control-list reference), and `pfam_accession`/`bit_score` when the
|
|
231
|
+
hit came from the sequence screen; the Proof panel renders them as Guardian's hit list does.
|
|
232
|
+
|
|
233
|
+
## [7.3.12] - 2026-07-09 - Guardian: local Pfam/HMMER sequence-domain screen (the Cargo sequence box is now screened)
|
|
234
|
+
|
|
235
|
+
### Added
|
|
236
|
+
- **A raw Cargo sequence (DNA/RNA/protein) is screened for the curated toxin families, not only a declared
|
|
237
|
+
Cargo function.** `sequence_homology()` was previously a no-op in this deployment (its `external_hook` was an
|
|
238
|
+
unwired extension point). `HazardRegistry` now has a `.default()` registry that wires
|
|
239
|
+
`pen_stack/safety/pfam_scan.py` as that hook: a cargo sequence is 6-frame-translated (DNA/RNA) or scanned
|
|
240
|
+
directly (protein) against bundled public Pfam profile HMMs for the same 17 accessions already in
|
|
241
|
+
`configs/safety/hazard_registry.yaml` (ricin/RIP, botulinum, diphtheria, anthrax, cholera, staph/strep
|
|
242
|
+
enterotoxin, conotoxin), using each profile's Pfam gathering (GA) cutoff, the threshold Pfam's own annotation
|
|
243
|
+
pipeline uses to call a family match. No hazard sequences are bundled: profile HMMs are public statistical
|
|
244
|
+
models built from many aligned sequences, not any one organism's sequence, consistent with the registry's
|
|
245
|
+
existing no-hazard-sequences policy. The screen reaches every entry point unchanged (`/api/safety`,
|
|
246
|
+
`/api/verify`, `/api/generate`, the Co-Scientist chat's design lane), since all funnel through `screen_design()`
|
|
247
|
+
→ the default registry: a sequence for a curated family refuses with no cargo_function declared, while benign
|
|
248
|
+
cargo (a GFP CDS fragment, a Factor IX fragment) stays clear. Scope: this covers the curated family list only
|
|
249
|
+
and is not a substitute for a full external homology screener (IBBIS Common Mechanism / SecureDNA) over a larger
|
|
250
|
+
reference set; an integrator can override via `HazardRegistry.load(external_hook=...)`.
|
|
251
|
+
- `provenance.declared_signal` (v7.3.11) now counts a submitted `cargo_seq`/`cargo_sequence` as signal, since it
|
|
252
|
+
is genuinely screened.
|
|
253
|
+
|
|
254
|
+
## [7.3.11] - 2026-07-09 - Guardian: distinguish an empty submission from a screened-clear result + Cargo function autofill fix
|
|
255
|
+
|
|
256
|
+
### Fixed
|
|
257
|
+
- **An empty Guardian submission is distinguished from a screened benign design.** With no cargo function, domain
|
|
258
|
+
tag, or taxon declared, `safety_gate` has no signal and correctly decides `clear`, but the badge and reason
|
|
259
|
+
("no hazard signal") were indistinguishable from a benign design ("human factor IX") that was actually checked.
|
|
260
|
+
`SafetyVerdict.provenance` now carries `declared_signal` (whether anything screenable was submitted); the reason
|
|
261
|
+
text reads "nothing was screened" when it is `False`, and the Guardian page renders a caveat: *"Nothing was
|
|
262
|
+
screened. 'Clear' here means there was no input to check, not a verified-safe result."*
|
|
263
|
+
- **Cargo function field text duplication.** The field had no `autoComplete` attribute, leaving it open to the
|
|
264
|
+
browser's autofill/suggestion heuristics interfering with a controlled input. `autoComplete="off"` is set on the
|
|
265
|
+
Cargo function and Gene/target inputs and the Cargo sequence textarea (the app's React state is the single source
|
|
266
|
+
of truth for these fields).
|
|
267
|
+
|
|
268
|
+
## [7.3.10] - 2026-07-08 - Stage H: promoter selector + cargo-capacity feasibility + mechanistic/learned transparency; multiplex verify fix
|
|
269
|
+
|
|
270
|
+
### Fixed
|
|
271
|
+
- **The multiplex plan (v7.3.9) now triggers its rule.** A multi-edit plan was sent with the original
|
|
272
|
+
`write_type` (e.g. `insertion`), whose rule categories exclude `multiplex`, so `multiplex.translocation_risk`
|
|
273
|
+
never ran (empty `soft_flags`). The plan now routes as `write_type="multiplex"`, so the translocation screen
|
|
274
|
+
fires (two DSB nucleases on different chromosomes → risk 0.64 flag; a DSB-free plan → ~zero).
|
|
275
|
+
- **The Digital Twin's top-level "Relative expression" reflects promoter and vehicle changes; its
|
|
276
|
+
cell-type-agnostic, per-copy basis is now explicit.** The mechanistic estimate is
|
|
277
|
+
`promoter × copy-number × accessibility × pre-existing-NAb`, with accessibility neutral (no cell-type chromatin
|
|
278
|
+
track mounted), **cell-type-agnostic** (the cell-type position effect is the learned Stage-H head) and
|
|
279
|
+
**per-copy** (independent of cargo size), so it did not move with cell type or cargo size. The page now (a)
|
|
280
|
+
exposes the **31-promoter palette** as a selector, a live lever the estimate reacts to (`GET /twin/promoters`,
|
|
281
|
+
`design.promoter`); (b) surfaces the **learned head's cell-type-aware relative expression** next to the
|
|
282
|
+
mechanistic headline, so a cell-type change is visible; (c) flags **cargo-over-capacity** as not-buildable
|
|
283
|
+
(`feasibility` in `/predict`); (d) states the mechanistic basis inline.
|
|
284
|
+
|
|
285
|
+
## [7.3.9] - 2026-07-08 - Design Studio: multiplex-plan UI + advisory (soft-penalty) flags surfaced
|
|
286
|
+
|
|
287
|
+
### Added
|
|
288
|
+
- **A "Plan multiple simultaneous edits" section on Design Studio** builds a 2–5-edit plan (chromosome / position /
|
|
289
|
+
writer-family rows) and sends it as `design.edits`, making the `multiplex.translocation_risk` legality rule
|
|
290
|
+
(implemented and rule-spec-published since v3.1, but with no UI path to `design.edits`) reachable. The default
|
|
291
|
+
two-row example matches the rule's own test fixture (two DSB nucleases on different chromosomes) and reproduces a
|
|
292
|
+
"flag" on first Verify.
|
|
293
|
+
- **Advisory (soft-penalty) flags are rendered on the Verify result.** `Verdict.soft_flags` was always computed
|
|
294
|
+
(multiplex translocation risk, AAV packaging margin, delivery sequence constraints, fold cross-loop
|
|
295
|
+
complementarity) but never rendered, since soft penalties do not fail legality and the Proof object's legality
|
|
296
|
+
axis never carried them. A new "Advisory flags" panel shows the rule id, reason, and value for any soft-penalty
|
|
297
|
+
rule that fires, labelled non-blocking.
|
|
298
|
+
|
|
299
|
+
## [7.3.8] - 2026-07-08 - Stage F: not_evaluated state under biosecurity refuse + standards concordance surfaced
|
|
300
|
+
|
|
301
|
+
### Fixed
|
|
302
|
+
- **The legality and confidence proof axes no longer report a verdict when biosecurity refuses a design.**
|
|
303
|
+
`verify.service.verify()` short-circuits on a biosecurity refuse and returns *before* the rules engine or
|
|
304
|
+
confidence calibration run (`legal=None`, `violations=[]`), a security-first fail-fast posture. `verify_proof()`'s
|
|
305
|
+
legality axis previously read that state as `status="fail"` with an empty violated list and no repair hint, and
|
|
306
|
+
the confidence axis read it as `status="abstain"` with a repair hint suggesting "supply the soft per-axis scores
|
|
307
|
+
to calibrate", which would not help. Both axes now report **`status="not_evaluated"`**, `ok=True` (an
|
|
308
|
+
unevaluated axis does not itself block; biosecurity already blocks `passable`), with an explanatory,
|
|
309
|
+
non-actionable repair hint. A genuine legality failure with no biosecurity hazard is unaffected (regression-tested).
|
|
310
|
+
|
|
311
|
+
### Added
|
|
312
|
+
- **Standards concordance (v6.12) is reachable via REST and rendered on the Guardian page.**
|
|
313
|
+
`concordance_report()` and `align_to_common_mechanism()` were implemented and unit-tested since v6.12 but had no
|
|
314
|
+
API endpoint or UI surface. `GET /safety/concordance` serves the labelled-probe-set report (8/8 concordant);
|
|
315
|
+
`POST /safety` additively carries a per-decision `standards` field (Common Mechanism ScreenStatus + SecureDNA
|
|
316
|
+
outcome), leaving the underlying decision unchanged. Guardian.jsx renders the per-screen standards alignment and
|
|
317
|
+
a concordance-benchmark card.
|
|
318
|
+
|
|
319
|
+
## [7.3.7] - 2026-07-08 - Writer immunogenicity: surface the human self control so the ADA foreignness term is visible
|
|
320
|
+
|
|
321
|
+
### Added
|
|
322
|
+
- **The Writer Atlas immunogenicity table surfaces the human self control (albumin) as a labelled reference
|
|
323
|
+
row.** Every genome writer is foreign (foreignness = 1), so the shipped rows could not show that
|
|
324
|
+
`ada_risk = MHC-II density × foreignness(origin)` is multiplicative, the numbers were indistinguishable from
|
|
325
|
+
`ada_risk = MHC-II load`. The self control (origin = self → foreignness 0) has a non-zero MHC-II density (0.32)
|
|
326
|
+
yet ADA-risk 0, so ADA decouples from the load: the row demonstrates that the foreignness term does real work
|
|
327
|
+
(central tolerance). `writer_immunogenicity_table()` appends it with `is_control: True`; the UI highlights it and
|
|
328
|
+
explains the decoupling; a test asserts control ada_risk 0 versus foreign writers ada_risk > 0.
|
|
329
|
+
|
|
330
|
+
## [7.3.6] - 2026-07-08 - Design Studio: immune-risk profile no longer shows stale numbers when the main vehicle changes
|
|
331
|
+
|
|
332
|
+
### Fixed
|
|
333
|
+
- **The Immune-risk profile card no longer desyncs from the main form's Delivery vehicle.** Changing the main-form
|
|
334
|
+
vehicle dropdown moved the profile card's highlighted vehicle chip (it tracked `design.delivery_vehicle`) while
|
|
335
|
+
the axis numbers stayed on the previously-profiled vehicle, so AAV numbers could be read as if they were LNP's.
|
|
336
|
+
The chip highlight now tracks the vehicle the profile was actually **computed for** (`immVehicle`), so chip and
|
|
337
|
+
numbers agree, and a banner appears when the main-form vehicle diverges ("These axes are for X … click its chip
|
|
338
|
+
or press Profile again to recompute for Y").
|
|
339
|
+
|
|
340
|
+
## [7.3.5] - 2026-07-08 - Off-Target auto-scroll hotfix (instant, not smooth)
|
|
341
|
+
|
|
342
|
+
### Fixed
|
|
343
|
+
- **The v7.3.4 auto-scroll-to-result now moves the viewport.** `scrollIntoView({behavior:"smooth"})` no-ops on
|
|
344
|
+
this app's scroll container; dropping `behavior:"smooth"` makes the Off-Target result reliably scroll into view
|
|
345
|
+
on the first click.
|
|
346
|
+
|
|
347
|
+
## [7.3.4] - 2026-07-08 - Off-Target page: scroll the result into view + guard rapid writer-class switches
|
|
348
|
+
|
|
349
|
+
### Fixed
|
|
350
|
+
- **The Off-Target finder result scrolls into view when it renders.** The page was the only finder missing the
|
|
351
|
+
shared auto-scroll-to-result pattern, so a result rendered below the tall explainer cards read as "no visible
|
|
352
|
+
output" on the first click. Adds a `resultsRef` and a `scrollIntoView` effect on busy/result/error, matching
|
|
353
|
+
Site Finder / Write Spec / Writer Atlas.
|
|
354
|
+
- **A slow previous-writer-class response can no longer clobber the current one.** `run()` tags each request and
|
|
355
|
+
only the latest may write `res`/`error`/`busy` (a request-id guard), so switching writer class and clicking in
|
|
356
|
+
quick succession renders the current selection's result.
|
|
357
|
+
|
|
358
|
+
## [7.3.3] - 2026-07-07 - Off-Target page copy: reflect SITE-seq, the chromatin annotation, and Cas12a in the on-page description and score guide
|
|
359
|
+
|
|
360
|
+
### Changed
|
|
361
|
+
- **Off-Target page `WhatYouGet` / `ScoreGuide` copy now documents the v7.3.1 capabilities** that were shipped in
|
|
362
|
+
the mechanics but not the descriptions: SITE-seq is named as the fourth grounding/confirming assay; the chromatin
|
|
363
|
+
accessibility annotation is described (validated, HEK293T DNase GUIDE-seq AUROC 0.671, annotation-only, not a
|
|
364
|
+
re-ranker); and Cas12a is noted as enumeration-supported but SpCas9-scorer-scoped (the finder abstains rather than
|
|
365
|
+
mis-scoring). No behavior change, copy only.
|
|
366
|
+
|
|
367
|
+
## [7.3.2] - 2026-07-07 - Digital Twin: surface the learned Stage-H position-effect head (served model + resolution-aware validation state)
|
|
368
|
+
|
|
369
|
+
### Added
|
|
370
|
+
- **Stage-H position-effect head surfaced on the Digital Twin page (`Twin.jsx`).** When a chromatin context is
|
|
371
|
+
supplied, the page shows which learned head served (human K562, Leemans 2019 / mESC TRIP), the served feature
|
|
372
|
+
resolution, and the `outcome_validated` flag, plus the learned log2-expression, its conformal interval and
|
|
373
|
+
p(silenced). An optional chromatin-context input (the head's five histone marks) enables the learned head from the
|
|
374
|
+
page. The human K562 head's validated regime (ρ≈0.57 at exact-site per-locus features) is distinguished from the
|
|
375
|
+
app's coarse 1 kb serving resolution, at which the head serves with `outcome_validated: false`.
|
|
376
|
+
- The `stage_h_mode` (learned vs heuristic) is shown as a pill on the predicted-outcome card.
|
|
377
|
+
- The human K562 position-effect head (`models/position_effect_human_k562.pkl`, Leemans 2019) and the mESC head
|
|
378
|
+
(`models/position_effect.pkl`) are staged into the served image so the v7.3.0 head loads at serve time (it was
|
|
379
|
+
wired in v7.3.0 but its artifact was not mounted); the artifacts are re-serialized in the serving image
|
|
380
|
+
(scikit-learn 1.9.0).
|
|
381
|
+
|
|
382
|
+
### Changed
|
|
383
|
+
- The Digital Twin `WhatYouGet` / `ScoreGuide` copy documents the learned Stage-H head and the exact-site vs coarse
|
|
384
|
+
1 kb resolution distinction.
|
|
385
|
+
|
|
386
|
+
## [7.3.1] - 2026-07-07 - Off-Target finder: SITE-seq in the assay recommender, chromatin-annotation surfacing, and Cas12a scoping
|
|
387
|
+
|
|
388
|
+
### Added
|
|
389
|
+
- **SITE-seq in the nuclease validation-assay recommender.** `offtarget_assay.recommend_assay` now lists SITE-seq
|
|
390
|
+
(Cameron et al., Nat Methods 2017; DOI 10.1038/nmeth.4284) alongside GUIDE-/CHANGE-/CIRCLE-seq, completing the
|
|
391
|
+
four unbiased assays the mismatch-calibrated risk band is grounded on.
|
|
392
|
+
- **Cas12a in the Off-Target finder writer-class selector (AsCas12a).** Genome-wide enumeration supports the Cas12a
|
|
393
|
+
TTTV 5' PAM, but the validated CRISOT-Score and the mismatch-calibrated risk band are SpCas9-specific; the finder
|
|
394
|
+
therefore reports that a validated Cas12a off-target scorer is not available rather than scoring Cas12a sites with
|
|
395
|
+
the SpCas9 model.
|
|
396
|
+
- **Chromatin-accessibility annotation surfaced on the nuclease finder result**: its standalone validation
|
|
397
|
+
(cell-type-matched HEK293T DNase; GUIDE-seq AUROC 0.671) plus a per-site accessibility column when the Stage B
|
|
398
|
+
accessibility track is mounted.
|
|
399
|
+
|
|
400
|
+
### Changed
|
|
401
|
+
- **The nuclease off-target `method` string and the `nominate_offtargets` capability manifest now describe the
|
|
402
|
+
chromatin layer precisely**, a validated annotation surfaced when the Stage B track is mounted (annotation-only,
|
|
403
|
+
not a re-ranker), instead of describing it unconditionally.
|
|
404
|
+
|
|
405
|
+
### Fixed
|
|
406
|
+
- **The nuclease finder no longer returns a chromatin field with no context when the Stage B accessibility track is
|
|
407
|
+
absent.** The result now carries `chromatin_available` and a note stating the annotation is track-gated and the
|
|
408
|
+
CRISOT-driven ranking is unaffected, in place of a silent null.
|
|
409
|
+
|
|
410
|
+
## [7.3.0] - 2026-07-04 - PEN-EXPRESS-HUMAN: a cell-type-matched Stage-H position-effect head for human K562 (Leemans 2019), replacing the non-transferring cross-species axis; served claim is resolution-aware
|
|
411
|
+
|
|
412
|
+
### Added
|
|
413
|
+
- **Human K562 position-effect head behind Stage H.** `twin.data.position_effect` now wires the **Leemans 2019**
|
|
414
|
+
human K562 dataset (Cell; PMID 30982597; DOI 10.1016/j.cell.2019.03.009) with a real loader (`_load_leemans`),
|
|
415
|
+
per-barcode coordinates fetched from the Cell supplement Dataset S2 joined to the van Steensel feature set.
|
|
416
|
+
`twin.position_effect.load_human_k562_model` + cell-type routing in `predict_stage_h` serve a `PositionEffectModel`
|
|
417
|
+
trained on human K562 for human K562 designs, falling back to the mESC model otherwise.
|
|
418
|
+
- Held-out validation (chromosome-blocked 5-fold OOF; n=9,298; 5 shared histone marks): expression Spearman
|
|
419
|
+
**ρ ≈ 0.59**, split-conformal held-out coverage **0.90** (nominal 0.90, within tolerance). This beats the mESC
|
|
420
|
+
model applied cross-species, which is an honest null on human K562 (held-out ρ ≈ 0.13, does not beat the
|
|
421
|
+
lamina/heterochromatin baseline ρ ≈ 0.39), and the trivial "avoid heterochromatin" baseline.
|
|
422
|
+
|
|
423
|
+
### Changed
|
|
424
|
+
- **The v6.7 cross-cell-type transfer axis is no longer data-gated.** With a human cell type now fetched, a human
|
|
425
|
+
K562 design's Stage-H provenance/scope reflect **human K562 supervision** instead of "single_context_supervision
|
|
426
|
+
(mESC), cross-cell-type transfer data-gated". `predict_stage_h` gains a `cell_type` argument (default `None`;
|
|
427
|
+
backward compatible; `twin.outcome` passes the cell state through).
|
|
428
|
+
|
|
429
|
+
### Serve-time honesty, resolution-aware `outcome_validated` scope
|
|
430
|
+
- The head's held-out validation (ρ ≈ 0.57 / +0.065 over a learned-heterochromatin baseline, CI [0.026, 0.103])
|
|
431
|
+
holds at **exact-site per-integration** chromatin-feature resolution. On coarse 1 kb-binned features even a
|
|
432
|
+
human-trained model realizes only **ρ ≈ 0.16** (P2_MATCHED_TRANSFER). `predict_stage_h` therefore stamps the
|
|
433
|
+
`human_K562_outcome_validated` scope **only when the caller declares exact-site features** (`feature_resolution`
|
|
434
|
+
/ `chromatin_features_resolution`, or `chromatin_ctx.resolution` ∈ exact-site set). Otherwise, including
|
|
435
|
+
undeclared resolution (conservative default), it returns `outcome_validated: False` and a downgraded flag
|
|
436
|
+
(`human_K562_head_served_UNVALIDATED_RESOLUTION …`) naming both numbers and the requirement. The prediction is
|
|
437
|
+
still served; only the validation claim is withheld until the served resolution matches the validated regime.
|
|
438
|
+
The output gains `served_feature_resolution` and `outcome_validated` fields.
|
|
439
|
+
- **Deferred to v7.4:** exact-site chromatin-feature extraction *at serve time* (point-query ChIP for an arbitrary
|
|
440
|
+
locus), so the served path realizes the validated ρ ≈ 0.57 directly and auto-earns the `outcome_validated` scope.
|
|
441
|
+
|
|
442
|
+
### Notes (honest scope)
|
|
443
|
+
- The cassette factorization (`f_cassette + g_context`) adds no value on Leemans' 6 similar promoters (factored
|
|
444
|
+
ρ 0.588 vs context-only ρ 0.592); additive suffices, reported not hidden. The served silenced (escaper/repressed)
|
|
445
|
+
call is promoter-driven, not a position signal. The head's validated output is steady-state **position-effect
|
|
446
|
+
expression in K562**, not temporal durability or other cell types.
|
|
447
|
+
- **Cross-species transfer is poor** (matched-source mouse↔human ρ ~0.08–0.20; P2_MATCHED_TRANSFER). The axis is
|
|
448
|
+
cell-type-specific; train a head per target cell type. An earlier draft over-read a feature-source-confounded
|
|
449
|
+
ρ 0.505 as transfer; corrected.
|
|
450
|
+
- The model artifact + Leemans parquet are deployment data (git-ignored under `data/`/`models/`, per the data
|
|
451
|
+
policy), not shipped in the wheel. Absent them, the human loader returns `None` and Stage H is unchanged.
|
|
452
|
+
|
|
6
453
|
## [7.2.3] - 2026-07-02 - Off-Target: professional wording (self-contained, no external-tool comparisons) + a plain-language explainer
|
|
7
454
|
|
|
8
455
|
### Changed
|
|
9
456
|
- **Removed all external-tool comparisons** ("like CRISPOR / CHOPCHOP", "CRISPOR-class", "CRISPOR-comparable") from
|
|
10
|
-
every off-target surface
|
|
457
|
+
every off-target surface, the Off-Target page, nav, code docstrings, REST docstring, the data card, `positioning.md`,
|
|
11
458
|
the prereg (re-SHA-locked), paper-4 prereg, and the v7.2.0 CHANGELOG entry. The capability is now described on its
|
|
12
|
-
own terms: a genome-wide off-target *finder
|
|
459
|
+
own terms: a genome-wide off-target *finder*. Given a guide/target, it enumerates and ranks the off-target sites
|
|
13
460
|
itself. No functional change.
|
|
14
461
|
- **Off-Target page now explains off-target effects in plain language**: a new top card covers *what an off-target
|
|
15
462
|
effect is*, *what you enter* (per writer class), and *what you get back* (ranked genome-wide sites with
|
|
@@ -19,25 +466,25 @@ All notable changes to PEN-STACK are documented here. This file follows
|
|
|
19
466
|
|
|
20
467
|
## [7.2.2] - 2026-07-02 - Integrase: precise capability framing (the negative is about a method, not the biology)
|
|
21
468
|
|
|
22
|
-
A framing/presentation refinement of the v7.2.1 sealed-negative result
|
|
469
|
+
A framing/presentation refinement of the v7.2.1 sealed-negative result: no science changes; the number is
|
|
23
470
|
unchanged and the negative stands.
|
|
24
471
|
|
|
25
472
|
### Changed
|
|
26
473
|
- **Precise claim, everywhere:** what the sealed PhiC31 benchmark showed is that a specific *method* (attP
|
|
27
|
-
sequence-similarity scanning) is insufficient
|
|
474
|
+
sequence-similarity scanning) is insufficient, **NOT** that pseudosites are unpredictable. The signal is real
|
|
28
475
|
(Chalberg's palindromic consensus; IntQuery's success on 410,776 cryptic attB), just not capturable by simple
|
|
29
476
|
identity. So the honest, narrow claim is "sequence similarity is insufficient," and this negative is the
|
|
30
477
|
empirical justification for a learned/DMS model (the indicated next step). Sharpened in `offtarget_integrase.py`,
|
|
31
478
|
`phic31_recall_metrics.json`, and the data card so nothing reads as "unpredictable."
|
|
32
479
|
- **App presentation:** `nominate_integrase` now returns a `capability` disclosure (badge + plain microcopy). The
|
|
33
480
|
Off-Target page shows a badge reading **"mechanism-based · not predictive by sequence alone"** (not a bare red
|
|
34
|
-
flag) plus one line
|
|
35
|
-
(sealed benchmark, negative); confirm empirically"
|
|
481
|
+
flag) plus one line, *"φC31 pseudosite activity is sequence-guided but not predictable from similarity alone
|
|
482
|
+
(sealed benchmark, negative); confirm empirically"*, separating the grounded facts (verified att + documented
|
|
36
483
|
pseudo-attP with GenBank accessions) from the honest capability limit. A trust-building disclosure, not an alarm.
|
|
37
484
|
|
|
38
485
|
## [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)
|
|
39
486
|
|
|
40
|
-
Closes the one genuine open item from v7.2.0
|
|
487
|
+
Closes the one genuine open item from v7.2.0, the PhiC31 integrase data gap, with independently-verified,
|
|
41
488
|
open, citable sequences (no fabrication) and a **sealed recall benchmark whose result is reported verbatim**.
|
|
42
489
|
|
|
43
490
|
### Added
|
|
@@ -49,16 +496,16 @@ open, citable sequences (no fabrication) and a **sealed recall benchmark whose r
|
|
|
49
496
|
DOI `10.1128/MCB.21.12.3926-3934.2001`; chr8/16/15). Corrected DOIs: Groth 2000 `10.1073/pnas.090527097`,
|
|
50
497
|
Chalberg 2006 `10.1016/j.jmb.2005.11.098` (was `...11.108`).
|
|
51
498
|
- **Sealed PhiC31 pseudo-attP recall benchmark** (`benchmarks/offtarget/integrase/`, O-G2): does attP-sequence-
|
|
52
|
-
similarity recover the documented pseudo-attP above length-matched GRCh38 background? **Result
|
|
499
|
+
similarity recover the documented pseudo-attP above length-matched GRCh38 background? **Result: NEGATIVE,
|
|
53
500
|
reported verbatim:** all three sites score 14 mm / 30 bp (53.3% identity), exactly the background **median**
|
|
54
501
|
(60.6% / 77.0% / 82.4% of random windows are as-or-more attP-similar). Sequence identity to attP is **not** a
|
|
55
|
-
validated PhiC31 pseudo-attP predictor
|
|
502
|
+
validated PhiC31 pseudo-attP predictor; φC31 recognition depends on palindromic architecture (Chalberg 2006) /
|
|
56
503
|
a learned model (IntQuery), not raw identity.
|
|
57
504
|
|
|
58
505
|
### Changed
|
|
59
506
|
- **Integrase status corrected: `semi_validated` → `mechanism_based_unvalidated` (with a sealed-NEGATIVE benchmark).**
|
|
60
507
|
The v7.2.0 "semi-validated (documented pseudosites as partial ground truth)" implied the sites validated the
|
|
61
|
-
method; the sealed benchmark shows they do not. This is a *stronger, more honest* outcome
|
|
508
|
+
method; the sealed benchmark shows they do not. This is a *stronger, more honest* outcome, a tested negative
|
|
62
509
|
rather than an untested claim. The verified att + documented pseudosites remain grounded facts and are surfaced
|
|
63
510
|
as verified known off-target loci. `nominate_integrase` PhiC31 returns the documented pseudo-attP + the sealed
|
|
64
511
|
benchmark; Bxb1 returns genome-wide similarity candidates carrying the same `similarity_ranking_validated: false`
|
|
@@ -67,33 +514,33 @@ open, citable sequences (no fabrication) and a **sealed recall benchmark whose r
|
|
|
67
514
|
|
|
68
515
|
## [7.2.0] - 2026-07-01 - PEN-OFFTGT v2: Stage E becomes a genome-wide, per-mechanism off-target FINDER (all 5 writer classes)
|
|
69
516
|
|
|
70
|
-
Stage E was a candidate *scorer
|
|
517
|
+
Stage E was a candidate *scorer*; it ranked off-target sites you supplied. An off-target *finder* instead takes
|
|
71
518
|
a guide/target and enumerates the genome-wide off-target sites itself. PEN-OFFTGT v2 closes that enumeration gap
|
|
72
519
|
AND applies the **correct off-target mechanism for each writer class**, each carrying a truthful per-mechanism
|
|
73
520
|
validation status (O-WS0–O-WS9 of the plan).
|
|
74
521
|
|
|
75
522
|
### Per-mechanism paths (O-WS3–O-WS6)
|
|
76
|
-
- **Serine integrase** (`offtarget_integrase.py`, O-WS3): a genome-wide **pseudo-attP** scan
|
|
523
|
+
- **Serine integrase** (`offtarget_integrase.py`, O-WS3): a genome-wide **pseudo-attP** scan, a fixed-sequence
|
|
77
524
|
Cas-OFFinder scan of the attP core window over GRCh38, scored by att-arm similarity. **Bxb1** is fully encoded
|
|
78
525
|
(FlyBase FBto0000359 / Ghosh 2003) and is highly specific. Status **semi-validated**. **PhiC31 is a disclosed
|
|
79
|
-
data gap** (its documented human pseudo-attP set
|
|
526
|
+
data gap** (its documented human pseudo-attP set, Chalberg 2006, could not be verified from an open source in
|
|
80
527
|
this build, so it abstains rather than fabricate). `data/curated/integrase_att.yaml`.
|
|
81
528
|
- **Bridge** (`offtarget_bridge.py`, O-WS4): wraps the existing DMS-scored genome scan (measured Perry-2025
|
|
82
|
-
specificity, held-out ranking AUROC 0.88). Status **hard-locked mechanism-based-unvalidated
|
|
529
|
+
specificity, held-out ranking AUROC 0.88). Status **hard-locked mechanism-based-unvalidated**; the ranker is
|
|
83
530
|
DMS-validated but **no genome-wide cellular off-target assay exists** for bridge recombinases, so genomic
|
|
84
531
|
recovery is unvalidated (stated in a no-ground-truth disclosure).
|
|
85
|
-
- **CAST** (`offtarget_cast.py` + `data/curated/cast_systems.yaml`, O-WS5)
|
|
532
|
+
- **CAST** (`offtarget_cast.py` + `data/curated/cast_systems.yaml`, O-WS5), NEW: guide-directed spacer scan +
|
|
86
533
|
the distinctive **guide-independent untargeted-transposition** background per system (ShCAST/Type V-K high +
|
|
87
534
|
AT-biased; VchCAST/Type I-F >95–99% on-target), all DOI-tagged. Status **mechanism-based-unvalidated**.
|
|
88
|
-
- **PASTE / (ee)PASSIGE** (`offtarget_paste.py`, O-WS6)
|
|
535
|
+
- **PASTE / (ee)PASSIGE** (`offtarget_paste.py`, O-WS6), NEW: composes the validated nuclease finder (Cas9
|
|
89
536
|
nickase, pegRNA) with the semi-validated integrase pseudo-attP scan (installed att); returns both component sets
|
|
90
537
|
and recommends BOTH a nuclease assay and an integrase assay. Status **composite**.
|
|
91
538
|
|
|
92
539
|
### Status labels + assay recommender (O-WS7) + disclosures (O-WS8 / gate O-G3)
|
|
93
540
|
- Every nomination carries a per-mechanism status label + the mechanism-appropriate confirm assay; `recommend_assay`
|
|
94
541
|
now covers CAST (transposon insertion-site seq) and PASTE (dual). `docs/cards/offtarget_data.md` documents the
|
|
95
|
-
per-mechanism ground-truth status
|
|
96
|
-
explicit no-ground-truth / data-gap disclosure (integrase-PhiC31, bridge, CAST)
|
|
542
|
+
per-mechanism ground-truth status, **O-G3: every mechanism has either a sealed benchmark (nuclease) or an
|
|
543
|
+
explicit no-ground-truth / data-gap disclosure (integrase-PhiC31, bridge, CAST), never a fabricated metric.**
|
|
97
544
|
- Disclosed deviations from the plan (no silent substitution): `att_pwm.json` → an att-similarity model in
|
|
98
545
|
`integrase_att.yaml` (a per-position PWM needs aligned pseudosites that do not exist at genome scale);
|
|
99
546
|
`bridge_dms_specificity.parquet` → the existing measured `bridge_offtarget_profile_measured.parquet` is reused;
|
|
@@ -108,11 +555,11 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
108
555
|
mismatch count. Supports SpCas9 (NGG), SaCas9 (NNGRRT), and Cas12a (TTTV, 5' PAM). A full scan is heavy, so it
|
|
109
556
|
runs **only on the VM** (`casoffinder:tools` Docker image, `docker/casoffinder.Dockerfile`); the live app
|
|
110
557
|
**replays a committed coordinate cache** for the canonical guides or **abstains honestly** for a novel one
|
|
111
|
-
(never fabricates sites)
|
|
558
|
+
(never fabricates sites), the same replay-or-abstain pattern as the heavy structure oracles. The enumerated
|
|
112
559
|
coordinates are facts from the public GRCh38 assembly (no license restriction), so the cache is committed
|
|
113
560
|
(`data/offtarget/enumerated_cache.parquet`, 8 canonical guides, 40,268 sites).
|
|
114
561
|
- **Nuclease off-target FINDER** (`pen_stack/wgenome/offtarget_nuclease.py`, O-WS2): chains enumeration into the
|
|
115
|
-
existing, validated scorer
|
|
562
|
+
existing, validated scorer, real CRISOT-Score → mismatch-calibrated risk band → chromatin annotation, so a
|
|
116
563
|
guide returns the genome-wide ranked off-target set *with coordinates*. Scoring is unchanged from v6.10 (still
|
|
117
564
|
validated: CRISOT beats homology on four unbiased assays); v2 adds the enumeration front end.
|
|
118
565
|
- **O-G1 gate PASSED**: enumeration recovers **100%** of EMX1's documented GUIDE-seq off-targets within the ≤5-mm
|
|
@@ -141,14 +588,14 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
141
588
|
immune & delivery" action correctly scopes to the **delivery/vehicle** axes (genotoxicity, CD8 capsid, innate,
|
|
142
589
|
pre-existing NAb, anti-PEG). `ImmuneProfileCard` hides the writer axes by default (`hideWriterAxes`).
|
|
143
590
|
- A new **Writer immunogenicity** card on the **Writer Atlas** surfaces each genome writer's MHC-II/CD4 epitope
|
|
144
|
-
load + ADA risk + human self-match, read from the **committed NetMHCIIpan-4.0 cache
|
|
591
|
+
load + ADA risk + human self-match, read from the **committed NetMHCIIpan-4.0 cache, not recomputed**
|
|
145
592
|
(`GET /api/writer/immune`, `immune_profile.writer_immunogenicity_table()`).
|
|
146
593
|
- **SpCas9 is removed** from the writer set: it is a nuclease/editor, not a large-cargo genome writer. The Writer
|
|
147
|
-
Atlas immunogenicity covers the actual writers
|
|
594
|
+
Atlas immunogenicity covers the actual writers, **Bxb1** (serine integrase) and **ISCro4** (bridge recombinase);
|
|
148
595
|
the Cas9 nuclease and the human self control are excluded. (The engine retains SpCas9 in its cache for other
|
|
149
596
|
uses; only the user-facing writer list drops it.)
|
|
150
597
|
- The engine still returns the `mhc2_writer` / `ada_writer` axes from `immune_profile()` for API/MCP callers that
|
|
151
|
-
pass a `writer_family
|
|
598
|
+
pass a `writer_family`; only the web UI moved the writer profiling to the Writer Atlas. No data was recomputed.
|
|
152
599
|
|
|
153
600
|
### Added
|
|
154
601
|
- `test_ws_profile.py`: `test_writer_immunogenicity_table_for_the_writer_atlas` (covers Bxb1 + ISCro4 from the
|
|
@@ -163,11 +610,11 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
163
610
|
grounded administration modifier (`immune_profile._administration_modifier` / `_apply_administration`):
|
|
164
611
|
- **Pre-existing NAb is muted to "no barrier" (1.0) ex vivo.** Ex-vivo delivery (cells transduced in a dish and
|
|
165
612
|
washed before transplant) never exposes the vector to the patient's circulating antibodies, so pre-existing
|
|
166
|
-
anti-vector NAb does not gate eligibility
|
|
613
|
+
anti-vector NAb does not gate eligibility; the eligibility fraction is 1.0 regardless of titer. The original
|
|
167
614
|
seroprevalence value is preserved (`pre_admin_value`) and the muting is explained in the axis note. This is the
|
|
168
615
|
same in-vivo/ex-vivo distinction the v5.1 `delivery_immunology` profile already encodes (`computed_ex_vivo_muted`).
|
|
169
616
|
- **CD8 capsid is flagged muted ex vivo** (systemic anti-capsid response minimal), but its intrinsic presentability
|
|
170
|
-
value is kept
|
|
617
|
+
value is kept; transduced cells can still present capsid epitopes, a real residual concern, so no number is
|
|
171
618
|
fabricated.
|
|
172
619
|
- **Genotoxicity, innate, anti-PEG and the writer axes are unchanged** by administration context (insertional risk
|
|
173
620
|
and cargo/writer immunogenicity are intrinsic, not a function of circulating-antibody exposure).
|
|
@@ -182,7 +629,7 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
182
629
|
## [7.1.6] - 2026-06-30 - Immune axes wired end-to-end + Delivery folded into Design Studio
|
|
183
630
|
|
|
184
631
|
### Fixed
|
|
185
|
-
- **Four immune-risk axes were unreachable from the web UI and showed as out-of-scope
|
|
632
|
+
- **Four immune-risk axes were unreachable from the web UI and showed as out-of-scope**: innate sensing, anti-PEG,
|
|
186
633
|
and the writer-as-antigen MHC-II + ADA axes abstained on every web design because the design form never collected
|
|
187
634
|
their inputs (the engine computed them correctly when called directly; this was a wiring gap, not a model gap):
|
|
188
635
|
- **`innate`** needs a cargo sequence. The design form now has an optional **Cargo sequence** field; the cargo
|
|
@@ -216,19 +663,19 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
216
663
|
### Added
|
|
217
664
|
- The `chrom` design field was a free-text pass-through with no validation and no downstream effect. It is now
|
|
218
665
|
meaningful (`pen_stack/planner/chromosome.py`):
|
|
219
|
-
- **Validation
|
|
666
|
+
- **Validation**: the web form's Chromosome input is a controlled dropdown (chr1–chr22, chrX, chrY, chrM), so
|
|
220
667
|
an impossible value like `chrZZZ` can no longer be entered; `canonical_chromosome()` normalises/validates on
|
|
221
668
|
the backend (`chrX`/`X`/`x`, `chr1`/`1`, `chrM`/`chrMT`/`MT`, `23`→X, `24`→Y; rejects the rest).
|
|
222
|
-
- **Gene/chromosome concordance
|
|
669
|
+
- **Gene/chromosome concordance**: `verify()` now flags `chromosome_mismatch` when the entered chromosome does
|
|
223
670
|
not match the named gene's canonical location (e.g. *BRCA1 is on chr17, not chr1*), `chromosome_invalid` for a
|
|
224
671
|
non-standard value, and `chromosome_unverifiable` for an unknown gene. The web form shows the warning inline
|
|
225
672
|
with a one-click fix, driven by the new `GET /api/gene/location` endpoint. This closes the silent-mismatch gap.
|
|
226
|
-
- **Chromosome context
|
|
227
|
-
flags: **chrM** is not addressable by nuclear genome-writing tools (mtDNA needs DdCBE/TALED
|
|
673
|
+
- **Chromosome context**: `chromosome_context()` adds grounded, chromosome-driven advisories surfaced as scope
|
|
674
|
+
flags: **chrM** is not addressable by nuclear genome-writing tools (mtDNA needs DdCBE/TALED, out of scope),
|
|
228
675
|
**chrY** is male-specific with ampliconic repeats, **chrX** is hemizygous in 46,XY vs X-inactivated in 46,XX.
|
|
229
676
|
- The Design Studio **cell-type dropdown now shows writability-atlas coverage** (from `/api/celltypes`): K562 /
|
|
230
677
|
HepG2 / HSPC are labelled measured (full / full / partial), while h1_hesc / iPSC / CD8 T / PBMC are labelled
|
|
231
|
-
"no atlas"
|
|
678
|
+
"no atlas", so a data-gated cell type is no longer silently indistinguishable from a measured one (the same
|
|
232
679
|
honest-field principle as the chromosome field). The 7 cell types are unchanged and already matched the backend.
|
|
233
680
|
|
|
234
681
|
### Note (honest scoping)
|
|
@@ -274,12 +721,12 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
274
721
|
receptor-binding / tropism, high severity) and `FUNC-ONCOGENIC-SUPPRESSOR` (dominant-negative TP53 / RB / PTEN,
|
|
275
722
|
apoptosis-checkpoint ablation, high severity), both DURC / HHS-P3CO categories.
|
|
276
723
|
- **Oncogenic-manipulation PATTERN screen** (`oncogenic_manipulation` in the registry +
|
|
277
|
-
`HazardRegistry.oncogenic_flags`): a flat keyword list is brittle to paraphrase
|
|
724
|
+
`HazardRegistry.oncogenic_flags`): a flat keyword list is brittle to paraphrase; a red-team pass found the
|
|
278
725
|
Guardian caught only **1/8** mechanism/synonym phrasings ("R175H p53 abolishing transactivation", "PTEN
|
|
279
726
|
knockout", "RAS G12D constitutive activation", "hTERT immortalization", "APC frameshift", "EGFR
|
|
280
727
|
ligand-independent activation", "NF1+BAX/BAK knockout"). The pattern screen flags the *combination*
|
|
281
728
|
`(tumor-suppressor + disruptive verb)` OR `(oncogene + activating signature)` OR `immortalization`, which
|
|
282
|
-
catches **8/8** while the deliberate asymmetry spares therapy with **no allow-list
|
|
729
|
+
catches **8/8** while the deliberate asymmetry spares therapy with **no allow-list**: restoring a suppressor or
|
|
283
730
|
silencing an oncogene matches neither, so "p53 correction to restore apoptosis", "TRAC/CCR5 knockout",
|
|
284
731
|
"knock-down of mutant KRAS" stay clear (**11/11** benign). Disposition is escalate (dual-use → human review).
|
|
285
732
|
- **Keyword matcher hardened** (`_kw_match`): a plain substring test made the ricin abbreviation `"rip"` fire
|
|
@@ -301,7 +748,7 @@ validation status (O-WS0–O-WS9 of the plan).
|
|
|
301
748
|
pbmc / h1_hesc / ipsc) returned an empty table, because the planner-backed `candidate_space` needs `plan_write`.
|
|
302
749
|
`generate_designs` now falls back to `space.vehicle_sweep(goal)`: it sweeps the capacity-compatible vehicles,
|
|
303
750
|
carries `cargo_function` (the Guardian still screens), runs full legality + biosecurity discrimination, and
|
|
304
|
-
ABSTAINS on the calibrated confidence (no fabricated band)
|
|
751
|
+
ABSTAINS on the calibrated confidence (no fabricated band), surfaced as "abstained, no measured atlas for this
|
|
305
752
|
cell type". `candidate_space` still returns `[]` without the atlas; `generate_designs(candidates=[])` still
|
|
306
753
|
returns `[]`.
|
|
307
754
|
- **Designer (administration context):** the vehicle sweep now filters by the goal's `in_vivo` flag using the
|