pen-stack 5.9.0__tar.gz → 5.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pen_stack-5.9.0 → pen_stack-5.11.0}/CHANGELOG.md +61 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/CITATION.cff +1 -1
- {pen_stack-5.9.0 → pen_stack-5.11.0}/PKG-INFO +46 -7
- {pen_stack-5.9.0 → pen_stack-5.11.0}/README.md +45 -6
- {pen_stack-5.9.0 → pen_stack-5.11.0}/benchmarks/genome_writing_bench/SHA256SUMS +1 -1
- {pen_stack-5.9.0 → pen_stack-5.11.0}/benchmarks/genome_writing_bench/tasks.yaml +36 -1
- pen_stack-5.11.0/docs/build_interface.md +50 -0
- pen_stack-5.11.0/docs/experiment_design.md +44 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/__init__.py +1 -1
- pen_stack-5.11.0/pen_stack/active/__init__.py +20 -0
- pen_stack-5.11.0/pen_stack/active/acquire.py +73 -0
- pen_stack-5.11.0/pen_stack/active/design.py +51 -0
- pen_stack-5.11.0/pen_stack/active/validate.py +104 -0
- pen_stack-5.11.0/pen_stack/build/__init__.py +16 -0
- pen_stack-5.11.0/pen_stack/build/ingest.py +47 -0
- pen_stack-5.11.0/pen_stack/build/protocol.py +82 -0
- pen_stack-5.11.0/pen_stack/build/simlab.py +30 -0
- pen_stack-5.11.0/pen_stack/validate/experiment_design.py +65 -0
- pen_stack-5.11.0/pen_stack/validate/protocol_safety.py +62 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/PKG-INFO +46 -7
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/SOURCES.txt +24 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_acq.json +8 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_aldesign.json +8 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_alvalidate.json +8 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_ingest.json +8 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_proto.json +8 -0
- pen_stack-5.11.0/prereg/SHA256_LOCK_ws_simlab.json +8 -0
- pen_stack-5.11.0/prereg/ws_acq.yaml +19 -0
- pen_stack-5.11.0/prereg/ws_aldesign.yaml +15 -0
- pen_stack-5.11.0/prereg/ws_alvalidate.yaml +19 -0
- pen_stack-5.11.0/prereg/ws_ingest.yaml +18 -0
- pen_stack-5.11.0/prereg/ws_proto.yaml +19 -0
- pen_stack-5.11.0/prereg/ws_simlab.yaml +17 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pyproject.toml +1 -1
- {pen_stack-5.9.0 → pen_stack-5.11.0}/LICENSE +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/MANIFEST.in +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/bench/run.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/benchmarks/genome_writing_bench/README.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/antipeg.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/atlas_families.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/bridge_offtarget_profile.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/capsid_epitope_oracle.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/capsid_sequences.fasta +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/cargo_polish.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/cell_types.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/datasets.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/delivery_constraints.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/delivery_rules.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/delivery_vehicles.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/gates_v3.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/genotoxicity_oracle.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/gsh_validated_heldout.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/intent_weights.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/known_unknowns.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/llm.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/monitor_queries.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/oracles/scope_cards.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/rules/delivery.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/rules/fold.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/rules/multiplex.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/rules/payload.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/rules/reachability.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/safety/hazard_registry.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/safety/policy.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/safety/probes.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/score_axes.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/seroprevalence.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/target_sites.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/universe_crosswalk.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/write_types.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/configs/wtkb_curated.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/data/curated/bridge_offtarget_energetics.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/data/curated/gene_coords.parquet +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/data/curated/unified_editor_universe.parquet +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/BACKLOG.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/DEPLOY.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/INFRA.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/MCP.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/RELEASING.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/REPRO.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/agent.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/alphagenome_feasibility.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/benchmark_circularity.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/biosecurity.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/cards/atlas.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/cards/durability.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/cards/safety.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/co_scientist.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/delivery.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/delivery_immunology.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/digital_twin.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/dissemination.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/environment.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/generative_design.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/index.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/mechanistic_constraints.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/oracles.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/positioning.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/private_data_formats.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/quickstart.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/responsible_use.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/rules.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/scope.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/scorecard.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/tutorials/compare-families.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/tutorials/score-deliverability.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/tutorials/where-can-i-write.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/tutorials/which-writer-reaches-locus.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/uncertainty.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/verify.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/world_model.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/writer_verification.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/docs/wtkb.md +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/_resources.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/finetune.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/ingest.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/pipeline.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/recalibrate.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/adapt/report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/cite.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/co_scientist.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/epistemic.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/guardrails.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/mcp_server.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/orchestrator.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/orchestrator_live.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/pen_agent.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/scope.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/agent/tools.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/build_wtkb.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/crosslink.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/expand.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/schema.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/scorecard.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/universe.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/variant_propose.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/atlas/writer_verify.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/activity.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/cli.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/fold_qc.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/guide_qc.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/ingest.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/offtarget.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/offtarget_energetics.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/ortholog_screen.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/bridge/pipeline.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/cli.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/encode.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/genome.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/ingest_chromatin.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/ingest_integration.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/ingest_safety_annot.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/data/ingest_trip.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/design/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/design/generate.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/design/pareto.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/design/space.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/env/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/env/genome_writing_env.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/env/policies.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/build.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/cell_types.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/ingest.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/query.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/graph/schema.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/mech/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/mech/classify_atlas.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/mech/whitelist.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/monitor/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/monitor/europepmc.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/monitor/run.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/monitor/triage.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/cache.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/energetics.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/genome.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/protein_design.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/rna.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/schema.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/structure.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/oracles/vcell.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/antipeg_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/cargo.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/cargo_polish.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/delivery.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/delivery_constraints.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/delivery_immunology.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/delivery_vehicles.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/genotoxicity_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/immune_profile.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/innate_sensing.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/multiplex.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/optimize.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/pipeline.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/router.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/seroprevalence_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/planner/target_site.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rag/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rag/index.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rag/llm.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rag/qa.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rules/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rules/evaluators.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rules/loader.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rules/schema.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/rules/solver.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/audit.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/gate.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/policy.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/redteam.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/registry.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/safety/screen.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/score/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/score/recalibrate.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/score/therapeutic.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/server/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/server/api.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/twin/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/twin/calibrate.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/twin/mechanistic.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/twin/outcome.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/ui/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/ui/app.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/adapt_demo.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/agent_eval.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_graph_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_rule_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_trust_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/bench_writetype_tasks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/blind_gsh_discovery.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/cargo_directionality.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/durability_baselines.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/forward_hypotheses.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/generative_design.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/guide_qc_demo.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/immune_calibration.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/intent_specification.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/out_of_scope_refusal.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/outcome_calibration.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/outcome_prediction.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/paper3_benchmark.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/paper4_real_validation.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/paper4_validation.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/safety_screening.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/selective_prediction.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/seq_vs_measured.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/target_site_controls.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/uncertainty_eval.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/ungrounded_baseline.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/within_locus_ranking.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/validate/writer_recovery.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/verify/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/verify/schema.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/verify/service.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/__init__.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/chromatin_seq.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/durability.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/export_tracks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/features.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/gsh_baseline.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/mesh_features.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/ood.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/providers.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/safety.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/structure3d.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/uncertainty.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack/wgenome/writability.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/dependency_links.txt +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/entry_points.txt +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/requires.txt +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/pen_stack.egg-info/top_level.txt +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_phase0.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_phase2.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_phase3.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_calib.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_gen.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_mech.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_orch.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_peg.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_policy.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_profile.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_r.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_screen.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/paper1.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/paper2.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/paper3.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/paper4.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/phase0.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_a.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_atlas.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_b.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_ba.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_ba_v33.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_ba_v45.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_bench.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_c.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_cal.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_calib.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_cite.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_crit.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_ct.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_d.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_e.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_env.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_ep.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_epitope.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_f.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_g.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_gen.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_genotox.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_graph.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_h.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_immune.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_innate.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_mc.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_mech.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_mon.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_o.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_orch.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_outcome.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_pareto.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_peg.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_plan.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_policy.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_profile.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_r.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_redteam.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_route.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_screen.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_seroprev.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_twincal.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_uq.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_v.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_vcell.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/prereg/ws_wv.yaml +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_build_atlas.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_build_durability.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_export_tracks.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_safety_concordance.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_train_safety.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p1_validation_report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p2_build_atlas.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p3_benchmark_report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p4_genome_scan.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p52_build_genotox_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/p53_build_epitope_oracle.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/ws_b_report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/scripts/ws_c_report.py +0 -0
- {pen_stack-5.9.0 → pen_stack-5.11.0}/setup.cfg +0 -0
|
@@ -3,6 +3,67 @@
|
|
|
3
3
|
All notable changes to PEN-STACK are documented here. This file follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/) and the program's phase structure.
|
|
5
5
|
|
|
6
|
+
## [5.11.0] - 2026-06-11 - v5.11 release: The Build Interface (digital→physical bridge)
|
|
7
|
+
|
|
8
|
+
**Closed-Loop arc, Cycle 5 of 7.** Make designs executable and results ingestible — loop-ready, lab-optional,
|
|
9
|
+
safety-gated, with the immune-risk profile attached as protocol metadata. Workstreams WS-{PROTO,INGEST,SIMLAB},
|
|
10
|
+
SHA-locked.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **WS-PROTO** — `pen_stack/build/protocol.py`: `export_protocol(design, experiment, target, actor)` for
|
|
14
|
+
Opentrons / PyLabRobot / cloud-lab. Runs `verify()` **first**: a safety-`refuse` or illegal design raises
|
|
15
|
+
**`ProtocolExportError`** (no export path for a flagged design); a cleared design is emitted as a **DRAFT**
|
|
16
|
+
("human/lab review required") carrying the v5.6 immune profile + provenance in its metadata. Never auto-run.
|
|
17
|
+
- **WS-INGEST** — `pen_stack/build/ingest.py`: `ingest_result(result, ...)` validates a result (assay / readout /
|
|
18
|
+
provenance) and turns it into a **quarantined measured edge Candidate**; the ONLY path into the curated
|
|
19
|
+
world-model is the v4.5 gate (`gate_admit`) — automated checks **and** explicit human approval. No auto-edit
|
|
20
|
+
(Principle 1). Immune measurements can begin validating the v5.6 proxies on a later pass.
|
|
21
|
+
- **WS-SIMLAB** — `pen_stack/build/simlab.py`: `run_simulated(protocol_ir, design, cell_state)` executes a
|
|
22
|
+
protocol in silico (samples from the v5.9 twin + measurement noise), **labelled `SIMULATED`**, so the closed
|
|
23
|
+
loop (v5.12) runs end-to-end **export → sim → ingest** without hardware; never enters the world-model as
|
|
24
|
+
measured truth.
|
|
25
|
+
- **WS-BENCH** — bench **v0.3.7**: new `protocol_safety` hard-gate task (`pen_stack/validate/protocol_safety.py`)
|
|
26
|
+
— a cleared design exports with immune metadata, a safety-refused/illegal design is blocked, and the simulated
|
|
27
|
+
loop completes with quarantined SIMULATED results; an ungated exporter (which would emit the hazardous protocol)
|
|
28
|
+
fails by construction.
|
|
29
|
+
- Docs: `docs/build_interface.md`; prereg `ws_{proto,ingest,simlab}` + SHA locks; deposit `phase_5.11/`.
|
|
30
|
+
|
|
31
|
+
### Notes
|
|
32
|
+
- PEN-STACK emits protocols and ingests results; it does **not** run experiments — protocols are drafts requiring
|
|
33
|
+
human/lab review, results enter only through the gate, and the simulated lab is for development / loop-validation,
|
|
34
|
+
never a substitute for real data. Export is hard-blocked for anything the safety gate flags.
|
|
35
|
+
|
|
36
|
+
## [5.10.0] - 2026-06-11 - v5.10 release: The Experiment Designer (active learning / EIG)
|
|
37
|
+
|
|
38
|
+
**Closed-Loop arc, Cycle 4 of 7.** The "Learn" brain of a self-driving lab: turn *"I'm uncertain"* into *"run
|
|
39
|
+
this experiment next."* Reads the calibrated v5.9 twin's uncertainty + the v5.6 immune labels, scores each
|
|
40
|
+
candidate experiment by expected information gain, assembles a diverse batch, and proves on held-out data — with
|
|
41
|
+
CIs — that this learns faster than random/greedy (reporting honestly when it does not). Workstreams
|
|
42
|
+
WS-{ACQ,DESIGN,VALIDATE}, SHA-locked.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **WS-ACQ** — `pen_stack/active/acquire.py`: `expected_information_gain` (reducible uncertainty from the twin's
|
|
46
|
+
predictive distribution; `≥ 0`, monotone in uncertainty), `predictive_entropy` (from the twin's interval width),
|
|
47
|
+
and **`immune_voi`** — value of information for **validating an immune PROXY axis** (v5.6): an experiment that
|
|
48
|
+
would measure a still-proxy axis is high-VOI (turns proxy → outcome-validated). `acquisition_score` is fully
|
|
49
|
+
traceable to twin quantities + v5.6 labels; deterministic; no fabricated values.
|
|
50
|
+
- **WS-DESIGN** — `pen_stack/active/design.py`: `select_batch` greedily maximises acquisition **minus a
|
|
51
|
+
redundancy penalty** (shared design facets) → a **diverse** batch (not k copies of the most-uncertain point);
|
|
52
|
+
each experiment carries its expected info gain.
|
|
53
|
+
- **WS-VALIDATE** — `pen_stack/active/validate.py`: `retrospective_active_learning` simulates active vs random vs
|
|
54
|
+
greedy campaigns on a held-out split, reports mean±CI learning curves and a **bootstrap CI on the curve-area
|
|
55
|
+
gap**; `active_beats_random` only when the CI excludes zero — else the not-yet-useful negative is reported.
|
|
56
|
+
- **WS-BENCH** — bench **v0.3.6**: new `experiment_design` hard-gate task — the gate is the Learn engine's
|
|
57
|
+
honesty + falsifiability (twin-sourced EIG monotone in uncertainty + immune-VOI for proxy validation + diverse
|
|
58
|
+
batch + retrospective active-vs-random with reps+CI); a random selector fails by construction. Active-beats-
|
|
59
|
+
random is reported informationally.
|
|
60
|
+
- Docs: `docs/experiment_design.md`; prereg `ws_{acq,aldesign,alvalidate}` + SHA locks; deposit `phase_5.10/`.
|
|
61
|
+
|
|
62
|
+
### Notes
|
|
63
|
+
- The experiment designer is only as good as the v5.9 twin + v5.6 labels it queries; its advantage is validated
|
|
64
|
+
**retrospectively** with CIs and reported honestly when absent. It chooses informative experiments but **does
|
|
65
|
+
not run them** — prospective benefit awaits a lab partner (v5.11+). No autonomy claim.
|
|
66
|
+
|
|
6
67
|
## [5.9.0] - 2026-06-11 - v5.9 release: The Digital Twin (calibrated outcome prediction)
|
|
7
68
|
|
|
8
69
|
**Closed-Loop arc, Cycle 3 of 7.** The missing layer: *what does the cell do after the write?* — predicted with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pen-stack
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.11.0
|
|
4
4
|
Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
|
|
5
5
|
Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -90,12 +90,12 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
90
90
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
91
91
|
[](LICENSE)
|
|
92
92
|
[](https://www.python.org/)
|
|
93
|
-
[](CHANGELOG.md)
|
|
94
|
+
[](tests/)
|
|
95
95
|
[](https://github.com/astral-sh/ruff)
|
|
96
96
|
[](docker/)
|
|
97
97
|
[](prereg/)
|
|
98
|
-
[](benchmarks/genome_writing_bench/)
|
|
99
99
|
|
|
100
100
|
**Built on five prior, separately published repositories:**
|
|
101
101
|
|
|
@@ -134,6 +134,40 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
|
|
|
134
134
|
Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
|
|
135
135
|
a pre-registered, honest baseline before release.
|
|
136
136
|
|
|
137
|
+
## What is new in v5.11 — The Build Interface (digital→physical bridge)
|
|
138
|
+
|
|
139
|
+
v5.11 (**Closed-Loop arc, Cycle 5 of 7**) makes designs executable and results ingestible — loop-ready,
|
|
140
|
+
lab-optional, **safety-gated**, with the immune-risk profile attached as protocol metadata. PEN-STACK emits
|
|
141
|
+
protocols and ingests results; it does **not** run experiments.
|
|
142
|
+
|
|
143
|
+
| Workstream | What it adds | Result |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| **PROTO** | `build/protocol.py` | `export_protocol` runs `verify()` first; a safety-refused/illegal design raises **`ProtocolExportError`**; a cleared design → a **DRAFT** (Opentrons/PyLabRobot/cloud-lab) carrying the v5.6 immune profile |
|
|
146
|
+
| **INGEST** | `build/ingest.py` | a result → a **quarantined measured Candidate**; the only path into the curated world-model is the v4.5 gate (checks + human approval) — **no auto-edit** |
|
|
147
|
+
| **SIMLAB** | `build/simlab.py` | `run_simulated` samples from the v5.9 twin (+ noise), **labelled SIMULATED**; the loop **export → sim → ingest** runs without hardware |
|
|
148
|
+
| **BENCH** | bench **v0.3.7** `protocol_safety` hard gate | cleared exports w/ immune metadata · hazard+illegal blocked · sim loop completes; an ungated exporter fails by construction |
|
|
149
|
+
|
|
150
|
+
Protocols are **drafts for human/lab review, never auto-executed**; export is hard-blocked for anything the safety
|
|
151
|
+
gate flags. See [`docs/build_interface.md`](docs/build_interface.md) and `prereg/ws_{proto,ingest,simlab}.yaml`.
|
|
152
|
+
|
|
153
|
+
## What is new in v5.10 — The Experiment Designer (active learning / EIG)
|
|
154
|
+
|
|
155
|
+
v5.10 (**Closed-Loop arc, Cycle 4 of 7**) is the **Learn** brain of a self-driving lab: it turns *"I'm
|
|
156
|
+
uncertain"* into *"run **this** experiment next."* It reads the calibrated v5.9 twin's uncertainty and the v5.6
|
|
157
|
+
immune labels, scores each candidate experiment by the information it is expected to yield, assembles a diverse
|
|
158
|
+
batch, and proves on held-out data — with confidence intervals — that this learns faster than random/greedy.
|
|
159
|
+
|
|
160
|
+
| Workstream | What it adds | Result |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| **ACQ** | `active/acquire.py` | EIG from the twin (≥0, monotone in uncertainty); **immune-VOI** rewards experiments that would validate a v5.6 **proxy** axis; deterministic, traceable |
|
|
163
|
+
| **DESIGN** | `active/design.py` | `select_batch` — diverse batch (acquisition − redundancy penalty), not k copies of the most-uncertain point; each carries expected info gain |
|
|
164
|
+
| **VALIDATE** | `active/validate.py` | retrospective active vs random/greedy learning curves with reps + **bootstrap CI** on the curve-area gap; beats random **only if CI excludes 0**, else reports not-yet-useful |
|
|
165
|
+
| **BENCH** | bench **v0.3.6** `experiment_design` hard gate | gate = the Learn engine's honesty + falsifiability; a random selector (no acquisition, no falsifiable curve) fails by construction |
|
|
166
|
+
|
|
167
|
+
Falsifiable by construction and **lab-optional** — it chooses informative experiments but does not run them
|
|
168
|
+
(prospective benefit awaits a lab; no autonomy claim). See [`docs/experiment_design.md`](docs/experiment_design.md)
|
|
169
|
+
and `prereg/ws_{acq,aldesign,alvalidate}.yaml`.
|
|
170
|
+
|
|
137
171
|
## What is new in v5.9 — The Digital Twin (calibrated outcome prediction)
|
|
138
172
|
|
|
139
173
|
v5.9 (**Closed-Loop arc, Cycle 3 of 7**) adds the missing layer — *what does the cell do after the write?* —
|
|
@@ -624,6 +658,8 @@ pen-stack/
|
|
|
624
658
|
│ ├── safety/ v5.7 the Guardian: biosecurity/dual-use gate (registry/screen/policy/gate/audit/redteam); runs first in verify(); refuse short-circuits; tamper-evident audit
|
|
625
659
|
│ ├── design/ v5.8 generative designer: space (candidate_space) / generate (verifier-as-discriminator; hazardous+illegal discarded) / pareto (frontier w/ grounded v5.6 immune axis)
|
|
626
660
|
│ ├── twin/ v5.9 digital twin: mechanistic (cassette expression, closed-form) / outcome (fuse mech+vcell+v5.6 immune; OOD widens interval; phenotype-bounded) / calibrate (honest two-sided)
|
|
661
|
+
│ ├── active/ v5.10 experiment designer: acquire (EIG/immune-VOI over the v5.9 twin) / design (diverse batch) / validate (retrospective active-vs-random, reps+CI, falsifiable)
|
|
662
|
+
│ ├── build/ v5.11 build interface: protocol (safety-gated export, DRAFT + v5.6 immune metadata) / ingest (typed gated -> v4.5 world-model, no auto-edit) / simlab (export->sim->ingest, SIMULATED)
|
|
627
663
|
│ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
|
|
628
664
|
│ ├── env/ v3.4 full Gymnasium environment over router+verifier (genome_writing_env + policies; [env] extra)
|
|
629
665
|
│ ├── monitor/ PEN-MONITOR living database (Europe PMC)
|
|
@@ -636,12 +672,14 @@ pen-stack/
|
|
|
636
672
|
│ │ v5.6 immune_calibration (proxy-vs-observed; labels each axis validated-or-proxy, two-sided) /
|
|
637
673
|
│ │ v5.7 safety_screening (the Guardian hard-gate: benign 0-false-refusal · hazards refused/escalated · evasions never clear) /
|
|
638
674
|
│ │ v5.8 generative_design (verifier-as-discriminator hard-gate: hazardous+illegal discarded; survivors calibrated+immune; grounded-immune Pareto) /
|
|
639
|
-
│ │ v5.9 outcome_prediction (digital-twin hard-gate: two-sided calibration + OOD widening + immune dim + phenotype out-of-scope)
|
|
675
|
+
│ │ v5.9 outcome_prediction (digital-twin hard-gate: two-sided calibration + OOD widening + immune dim + phenotype out-of-scope) /
|
|
676
|
+
│ │ v5.10 experiment_design (active-learning hard-gate: EIG monotone + immune-VOI + diverse batch + retrospective active-vs-random reps+CI) /
|
|
677
|
+
│ │ v5.11 protocol_safety (build-interface hard-gate: cleared exports w/ immune metadata · hazard+illegal blocked · sim loop completes)
|
|
640
678
|
│ ├── data/ ingestion (genome, chromatin, integration, TRIP, safety annotations)
|
|
641
679
|
│ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
|
|
642
680
|
│ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
|
|
643
681
|
│ └── cli.py unified CLI
|
|
644
|
-
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3.
|
|
682
|
+
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3.7 (T1-T16 + co_scientist + safety_screening + generative_design + outcome_prediction + experiment_design + protocol_safety; tasks / harness / solvers / LEADERBOARD / SHAs)
|
|
645
683
|
├── bench/run.py one-command bench entrypoint (--agent, --verify)
|
|
646
684
|
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
|
|
647
685
|
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
|
|
@@ -653,7 +691,8 @@ pen-stack/
|
|
|
653
691
|
├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.9 ws_{uq,ep,mc,ba,
|
|
654
692
|
│ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
|
|
655
693
|
│ genotox,epitope,innate,seroprev,peg,calib,profile,screen,policy,redteam,
|
|
656
|
-
│ gen,pareto,orch,vcell,mech,outcome,twincal
|
|
694
|
+
│ gen,pareto,orch,vcell,mech,outcome,twincal,acq,aldesign,alvalidate,
|
|
695
|
+
│ proto,ingest,simlab} + SHA256 locks)
|
|
657
696
|
├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
|
|
658
697
|
│ v3.2 bridge_offtarget_energetics.json)
|
|
659
698
|
├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
|
|
@@ -15,12 +15,12 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
|
|
|
15
15
|
[](https://codecov.io/gh/ahmedanees-m/pen-stack)
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](https://www.python.org/)
|
|
18
|
-
[](CHANGELOG.md)
|
|
19
|
+
[](tests/)
|
|
20
20
|
[](https://github.com/astral-sh/ruff)
|
|
21
21
|
[](docker/)
|
|
22
22
|
[](prereg/)
|
|
23
|
-
[](benchmarks/genome_writing_bench/)
|
|
24
24
|
|
|
25
25
|
**Built on five prior, separately published repositories:**
|
|
26
26
|
|
|
@@ -59,6 +59,40 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
|
|
|
59
59
|
Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
|
|
60
60
|
a pre-registered, honest baseline before release.
|
|
61
61
|
|
|
62
|
+
## What is new in v5.11 — The Build Interface (digital→physical bridge)
|
|
63
|
+
|
|
64
|
+
v5.11 (**Closed-Loop arc, Cycle 5 of 7**) makes designs executable and results ingestible — loop-ready,
|
|
65
|
+
lab-optional, **safety-gated**, with the immune-risk profile attached as protocol metadata. PEN-STACK emits
|
|
66
|
+
protocols and ingests results; it does **not** run experiments.
|
|
67
|
+
|
|
68
|
+
| Workstream | What it adds | Result |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| **PROTO** | `build/protocol.py` | `export_protocol` runs `verify()` first; a safety-refused/illegal design raises **`ProtocolExportError`**; a cleared design → a **DRAFT** (Opentrons/PyLabRobot/cloud-lab) carrying the v5.6 immune profile |
|
|
71
|
+
| **INGEST** | `build/ingest.py` | a result → a **quarantined measured Candidate**; the only path into the curated world-model is the v4.5 gate (checks + human approval) — **no auto-edit** |
|
|
72
|
+
| **SIMLAB** | `build/simlab.py` | `run_simulated` samples from the v5.9 twin (+ noise), **labelled SIMULATED**; the loop **export → sim → ingest** runs without hardware |
|
|
73
|
+
| **BENCH** | bench **v0.3.7** `protocol_safety` hard gate | cleared exports w/ immune metadata · hazard+illegal blocked · sim loop completes; an ungated exporter fails by construction |
|
|
74
|
+
|
|
75
|
+
Protocols are **drafts for human/lab review, never auto-executed**; export is hard-blocked for anything the safety
|
|
76
|
+
gate flags. See [`docs/build_interface.md`](docs/build_interface.md) and `prereg/ws_{proto,ingest,simlab}.yaml`.
|
|
77
|
+
|
|
78
|
+
## What is new in v5.10 — The Experiment Designer (active learning / EIG)
|
|
79
|
+
|
|
80
|
+
v5.10 (**Closed-Loop arc, Cycle 4 of 7**) is the **Learn** brain of a self-driving lab: it turns *"I'm
|
|
81
|
+
uncertain"* into *"run **this** experiment next."* It reads the calibrated v5.9 twin's uncertainty and the v5.6
|
|
82
|
+
immune labels, scores each candidate experiment by the information it is expected to yield, assembles a diverse
|
|
83
|
+
batch, and proves on held-out data — with confidence intervals — that this learns faster than random/greedy.
|
|
84
|
+
|
|
85
|
+
| Workstream | What it adds | Result |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| **ACQ** | `active/acquire.py` | EIG from the twin (≥0, monotone in uncertainty); **immune-VOI** rewards experiments that would validate a v5.6 **proxy** axis; deterministic, traceable |
|
|
88
|
+
| **DESIGN** | `active/design.py` | `select_batch` — diverse batch (acquisition − redundancy penalty), not k copies of the most-uncertain point; each carries expected info gain |
|
|
89
|
+
| **VALIDATE** | `active/validate.py` | retrospective active vs random/greedy learning curves with reps + **bootstrap CI** on the curve-area gap; beats random **only if CI excludes 0**, else reports not-yet-useful |
|
|
90
|
+
| **BENCH** | bench **v0.3.6** `experiment_design` hard gate | gate = the Learn engine's honesty + falsifiability; a random selector (no acquisition, no falsifiable curve) fails by construction |
|
|
91
|
+
|
|
92
|
+
Falsifiable by construction and **lab-optional** — it chooses informative experiments but does not run them
|
|
93
|
+
(prospective benefit awaits a lab; no autonomy claim). See [`docs/experiment_design.md`](docs/experiment_design.md)
|
|
94
|
+
and `prereg/ws_{acq,aldesign,alvalidate}.yaml`.
|
|
95
|
+
|
|
62
96
|
## What is new in v5.9 — The Digital Twin (calibrated outcome prediction)
|
|
63
97
|
|
|
64
98
|
v5.9 (**Closed-Loop arc, Cycle 3 of 7**) adds the missing layer — *what does the cell do after the write?* —
|
|
@@ -549,6 +583,8 @@ pen-stack/
|
|
|
549
583
|
│ ├── safety/ v5.7 the Guardian: biosecurity/dual-use gate (registry/screen/policy/gate/audit/redteam); runs first in verify(); refuse short-circuits; tamper-evident audit
|
|
550
584
|
│ ├── design/ v5.8 generative designer: space (candidate_space) / generate (verifier-as-discriminator; hazardous+illegal discarded) / pareto (frontier w/ grounded v5.6 immune axis)
|
|
551
585
|
│ ├── twin/ v5.9 digital twin: mechanistic (cassette expression, closed-form) / outcome (fuse mech+vcell+v5.6 immune; OOD widens interval; phenotype-bounded) / calibrate (honest two-sided)
|
|
586
|
+
│ ├── active/ v5.10 experiment designer: acquire (EIG/immune-VOI over the v5.9 twin) / design (diverse batch) / validate (retrospective active-vs-random, reps+CI, falsifiable)
|
|
587
|
+
│ ├── build/ v5.11 build interface: protocol (safety-gated export, DRAFT + v5.6 immune metadata) / ingest (typed gated -> v4.5 world-model, no auto-edit) / simlab (export->sim->ingest, SIMULATED)
|
|
552
588
|
│ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
|
|
553
589
|
│ ├── env/ v3.4 full Gymnasium environment over router+verifier (genome_writing_env + policies; [env] extra)
|
|
554
590
|
│ ├── monitor/ PEN-MONITOR living database (Europe PMC)
|
|
@@ -561,12 +597,14 @@ pen-stack/
|
|
|
561
597
|
│ │ v5.6 immune_calibration (proxy-vs-observed; labels each axis validated-or-proxy, two-sided) /
|
|
562
598
|
│ │ v5.7 safety_screening (the Guardian hard-gate: benign 0-false-refusal · hazards refused/escalated · evasions never clear) /
|
|
563
599
|
│ │ v5.8 generative_design (verifier-as-discriminator hard-gate: hazardous+illegal discarded; survivors calibrated+immune; grounded-immune Pareto) /
|
|
564
|
-
│ │ v5.9 outcome_prediction (digital-twin hard-gate: two-sided calibration + OOD widening + immune dim + phenotype out-of-scope)
|
|
600
|
+
│ │ v5.9 outcome_prediction (digital-twin hard-gate: two-sided calibration + OOD widening + immune dim + phenotype out-of-scope) /
|
|
601
|
+
│ │ v5.10 experiment_design (active-learning hard-gate: EIG monotone + immune-VOI + diverse batch + retrospective active-vs-random reps+CI) /
|
|
602
|
+
│ │ v5.11 protocol_safety (build-interface hard-gate: cleared exports w/ immune metadata · hazard+illegal blocked · sim loop completes)
|
|
565
603
|
│ ├── data/ ingestion (genome, chromatin, integration, TRIP, safety annotations)
|
|
566
604
|
│ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
|
|
567
605
|
│ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
|
|
568
606
|
│ └── cli.py unified CLI
|
|
569
|
-
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3.
|
|
607
|
+
├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3.7 (T1-T16 + co_scientist + safety_screening + generative_design + outcome_prediction + experiment_design + protocol_safety; tasks / harness / solvers / LEADERBOARD / SHAs)
|
|
570
608
|
├── bench/run.py one-command bench entrypoint (--agent, --verify)
|
|
571
609
|
├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
|
|
572
610
|
├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
|
|
@@ -578,7 +616,8 @@ pen-stack/
|
|
|
578
616
|
├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.9 ws_{uq,ep,mc,ba,
|
|
579
617
|
│ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
|
|
580
618
|
│ genotox,epitope,innate,seroprev,peg,calib,profile,screen,policy,redteam,
|
|
581
|
-
│ gen,pareto,orch,vcell,mech,outcome,twincal
|
|
619
|
+
│ gen,pareto,orch,vcell,mech,outcome,twincal,acq,aldesign,alvalidate,
|
|
620
|
+
│ proto,ingest,simlab} + SHA256 locks)
|
|
582
621
|
├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
|
|
583
622
|
│ v3.2 bridge_offtarget_energetics.json)
|
|
584
623
|
├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
5901339c67024897aa2cce9fbf1ac93676b6d88ffcec55126033c8b39a6d2a70 benchmarks/genome_writing_bench/tasks.yaml
|
|
2
2
|
5ca511c6763b4e3703e8009031ff8dc385c2a99540e2731d875a9fbbb16f5ecd configs/gsh_validated_heldout.yaml
|
|
3
3
|
758817c1e46c7db10f7f942316663367c5f297cac0cf2f59947a90638a256718 data/writer_panel.csv
|
|
4
4
|
865b18ff23d140c3df6f3b5f25398581ebdfe3534e1cecf6f512afb540ab5ede data/gsh_matched_controls.parquet
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# A task names a `scorer` (module.function in pen_stack.validate / pen_stack.bridge) and a `metric` key to
|
|
9
9
|
# read from its report. Solvers (deterministic planner, naive baseline, LLM agent) are compared on the same
|
|
10
10
|
# tasks; a solver that cannot ground a number must refuse, not invent (no-fabrication is a hard gate).
|
|
11
|
-
version: "0.3.
|
|
11
|
+
version: "0.3.7"
|
|
12
12
|
prepared: "2026-06-11"
|
|
13
13
|
|
|
14
14
|
taxonomy:
|
|
@@ -43,6 +43,10 @@ taxonomy:
|
|
|
43
43
|
GD_generative_design: "generate candidate writing systems and keep ONLY legal+safe+calibrated+immune-profiled survivors (hazardous toxin payload + illegal oversize/form-incompatible designs DISCARDED), returning a Pareto frontier with a grounded immune-risk axis (vs an ungrounded generator that ships hazardous/illegal designs)"
|
|
44
44
|
# v0.3.5 (v5.9): the digital twin - calibrated, OOD-aware, immune-aware, phenotype-bounded outcome prediction.
|
|
45
45
|
OP_outcome_prediction: "predict a write's computable outcome with HONEST calibration (two-sided MAE-vs-naive with bootstrap CI), an interval that WIDENS under OOD, an immune-outcome dimension from v5.6, and phenotype out of scope (vs an overconfident predictor with a fixed narrow interval and no scope awareness)"
|
|
46
|
+
# v0.3.6 (v5.10): the experiment designer - active learning / EIG, falsifiable vs random/greedy.
|
|
47
|
+
ED_experiment_design: "choose the experiment(s) that most reduce model uncertainty: EIG from the calibrated twin (monotone in uncertainty), immune-VOI rewarding proxy-validating experiments, a diverse batch, and a RETROSPECTIVE active-vs-random validation with reps + bootstrap CI (vs a random selector with no acquisition signal and no falsifiable curve)"
|
|
48
|
+
# v0.3.7 (v5.11): the build interface - safety-gated protocol export + gated ingestion + simulated loop.
|
|
49
|
+
PS_protocol_safety: "export a cleared design as a runnable protocol DRAFT carrying its v5.6 immune profile, BLOCK any safety-refused/illegal design (ProtocolExportError), and complete the simulated loop export->sim->ingest with results quarantined (no auto-edit) + labelled SIMULATED (vs an ungated exporter that would emit the hazardous protocol)"
|
|
46
50
|
|
|
47
51
|
tasks:
|
|
48
52
|
- id: site_selection_blind_gsh
|
|
@@ -280,3 +284,34 @@ tasks:
|
|
|
280
284
|
note: "v5.9 the digital twin: a trustworthy predictor is calibrated + OOD-aware + immune-aware + phenotype-
|
|
281
285
|
bounded; an overconfident predictor (fixed narrow interval, no OOD/scope awareness) fails the gate by
|
|
282
286
|
construction. Honest about what the field cannot yet do."
|
|
287
|
+
|
|
288
|
+
- id: experiment_design
|
|
289
|
+
family: ED_experiment_design
|
|
290
|
+
scorer: "pen_stack.validate.experiment_design:run"
|
|
291
|
+
metric: "experiment_designer_honest"
|
|
292
|
+
baseline_metric: "random_selector_honest"
|
|
293
|
+
higher_is_better: true
|
|
294
|
+
hard_gate: true
|
|
295
|
+
gate_rule: "experiment_designer_honest == True (EIG monotone in uncertainty AND immune-VOI rewards proxy validation AND batch diverse AND retrospective active-vs-random reported with reps+CI)"
|
|
296
|
+
ground_truth: "structural honesty + falsifiability properties of the Learn engine (twin-sourced EIG, immune-VOI,
|
|
297
|
+
diverse batch, retrospective active-vs-random with reps + bootstrap CI), NOT a beat-the-world claim -
|
|
298
|
+
non-circular; the active-beats-random outcome is reported either way (not-yet-useful is a valid result)"
|
|
299
|
+
circular: false
|
|
300
|
+
note: "v5.10 the experiment designer: a trustworthy Learn engine computes acquisition from the calibrated twin,
|
|
301
|
+
rewards proxy-validating experiments, selects a diverse batch, and validates active-vs-random retrospectively
|
|
302
|
+
with CIs; a random selector has no acquisition signal and no falsifiable curve and fails by construction."
|
|
303
|
+
|
|
304
|
+
- id: protocol_safety
|
|
305
|
+
family: PS_protocol_safety
|
|
306
|
+
scorer: "pen_stack.validate.protocol_safety:run"
|
|
307
|
+
metric: "build_safety_honored"
|
|
308
|
+
baseline_metric: "ungated_exporter_safe"
|
|
309
|
+
higher_is_better: true
|
|
310
|
+
hard_gate: true
|
|
311
|
+
gate_rule: "build_safety_honored == True (cleared exports w/ immune metadata AND hazard+illegal blocked AND sim labelled AND export->sim->ingest completes w/ quarantine)"
|
|
312
|
+
ground_truth: "export blocking decided by the v5.7 safety gate + the rules (not the exporter); ingestion gated by
|
|
313
|
+
the v4.5 world-model gate (no auto-edit of curated truth); sim results labelled SIMULATED - non-circular"
|
|
314
|
+
circular: false
|
|
315
|
+
note: "v5.11 the build interface: a cleared design exports a DRAFT carrying its immune profile; a safety-refused
|
|
316
|
+
or illegal design raises ProtocolExportError; the simulated loop completes with quarantined, SIMULATED-labelled
|
|
317
|
+
results. An ungated exporter would emit the hazardous protocol and fails by construction."
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# The build interface (v5.11)
|
|
2
|
+
|
|
3
|
+
From v5.11, PEN-STACK reaches the **digital→physical** interface — responsibly. A cleared, legal design becomes a
|
|
4
|
+
runnable protocol DRAFT carrying its v5.6 immune-risk profile (refused outright if the v5.7 safety gate flags it);
|
|
5
|
+
a typed ingestion API returns experimental results as candidate evidence admitted only through the v4.5
|
|
6
|
+
world-model gate; and a simulated lab runs the whole loop before any hardware exists. PEN-STACK **emits protocols
|
|
7
|
+
and ingests results — it does not run experiments.**
|
|
8
|
+
|
|
9
|
+
## Safety-gated protocol export (`pen_stack/build/protocol.py`)
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from pen_stack.build import export_protocol, ProtocolExportError
|
|
13
|
+
code = export_protocol(design, {"round": 0}, target="opentrons", actor="lab-alice")
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`export_protocol` runs `verify(design, actor)` **first**. If the safety gate returns `refuse`, or the design is
|
|
17
|
+
illegal, it raises **`ProtocolExportError`** — there is no export path for a flagged design. A cleared design is
|
|
18
|
+
emitted for one of `opentrons` / `pylabrobot` / `cloudlab`, **stamped "DRAFT — human/lab review required"**, with
|
|
19
|
+
the v5.6 immune profile and full provenance in the metadata. Protocols are drafts; nothing is auto-run.
|
|
20
|
+
|
|
21
|
+
## Typed, gated ingestion (`pen_stack/build/ingest.py`)
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from pen_stack.build import ingest_result
|
|
25
|
+
cand = ingest_result(result) # quarantined measured Candidate (no auto-merge)
|
|
26
|
+
ingest_result(result, admitted_by="human", graph=g, approved=True) # the ONLY path into the curated graph
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
A result is validated (assay / readout / provenance with a source) and turned into a **quarantined measured edge
|
|
30
|
+
Candidate**. The only way it enters the curated world-model is the v4.5 gate (`gate_admit`) — automated checks
|
|
31
|
+
**and** explicit human approval. No process auto-edits curated truth (Principle 1). Immune-measurement results can
|
|
32
|
+
begin validating the v5.6 proxies on a later pass.
|
|
33
|
+
|
|
34
|
+
## Simulated lab (`pen_stack/build/simlab.py`)
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from pen_stack.build import run_simulated
|
|
38
|
+
res = run_simulated(protocol_ir, design, cell_state="k562", seed=0)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`run_simulated` executes a protocol in silico: it samples an "observed" readout from the v5.9 twin + measurement
|
|
42
|
+
noise, **labelled `SIMULATED`**. This lets the closed loop (v5.12) run end-to-end **export → sim → ingest** without
|
|
43
|
+
a wet lab. Sim outcomes inherit the twin's limits and **never** enter the curated world-model as measured truth.
|
|
44
|
+
|
|
45
|
+
## Honest scope
|
|
46
|
+
|
|
47
|
+
PEN-STACK emits protocols and ingests results; it does **not** run experiments — protocols are drafts requiring
|
|
48
|
+
human/lab review, results enter only through the gate, and the simulated lab is for development and loop-validation,
|
|
49
|
+
never a substitute for real data. Export is hard-blocked for anything the safety gate flags; the attached immune
|
|
50
|
+
profile is a screen carrying its known-unknowns, not a patient prediction.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# The experiment designer (v5.10)
|
|
2
|
+
|
|
3
|
+
From v5.10, PEN-STACK turns *"I'm uncertain"* into *"run **this** experiment next."* It reads the calibrated v5.9
|
|
4
|
+
twin's uncertainty and the v5.6 immune-risk labels, scores each candidate experiment by the information it is
|
|
5
|
+
expected to yield, assembles a diverse batch, and proves on held-out data — with confidence intervals — that this
|
|
6
|
+
learns faster than random or greedy, reporting honestly when it does not. The **Learn** brain of a self-driving
|
|
7
|
+
lab: lab-optional and falsifiable by construction.
|
|
8
|
+
|
|
9
|
+
## Acquisition (`pen_stack/active/acquire.py`)
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from pen_stack.active import acquisition_score, expected_information_gain, immune_voi
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- **`predictive_entropy(outcome)`** — the twin's current uncertainty, from its interval width (Gaussian
|
|
16
|
+
differential entropy).
|
|
17
|
+
- **`expected_information_gain(candidate, cell_state)`** — reducible uncertainty: `entropy now − expected
|
|
18
|
+
posterior entropy` (a measurement collapses the predictive sd toward a noise floor); `≥ 0`. Monotone in the
|
|
19
|
+
twin's uncertainty (an OOD candidate yields more EIG).
|
|
20
|
+
- **`immune_voi(candidate)`** — value of information for **validating an immune PROXY axis** (v5.6): an axis still
|
|
21
|
+
labelled a proxy that this experiment would measure is high-VOI (it would turn proxy → outcome-validated).
|
|
22
|
+
- **`acquisition_score`** = `w_eig·EIG + w_unc·entropy + w_imm·immune_voi`. Fully traceable to twin quantities +
|
|
23
|
+
v5.6 labels; deterministic given inputs (no fabricated values).
|
|
24
|
+
|
|
25
|
+
## Diverse batch (`pen_stack/active/design.py`)
|
|
26
|
+
|
|
27
|
+
`select_batch(candidates, cell_state, k)` greedily maximises summed acquisition **minus a redundancy penalty**
|
|
28
|
+
(shared design facets) against the already-chosen set — so a batch is a *diverse* set of informative experiments,
|
|
29
|
+
not k copies of the single most-uncertain point. Each chosen experiment carries its `expected_info_gain`.
|
|
30
|
+
|
|
31
|
+
## Retrospective falsifiability (`pen_stack/active/validate.py`)
|
|
32
|
+
|
|
33
|
+
`retrospective_active_learning(dataset, strategies=("active","random","greedy"))` simulates campaigns per
|
|
34
|
+
strategy on a held-out split, records the held-out-MAE learning curve per round, and over repetitions reports
|
|
35
|
+
mean±CI curves and a **bootstrap CI on the curve-area gap** (`random_area − active_area`). The active learner
|
|
36
|
+
"beats" random **only when the CI excludes zero**; otherwise the not-yet-useful negative is reported verbatim — a
|
|
37
|
+
valid, published outcome.
|
|
38
|
+
|
|
39
|
+
## Honest scope
|
|
40
|
+
|
|
41
|
+
The experiment designer is only as good as the v5.9 twin and the v5.6 labels it queries. Its advantage is
|
|
42
|
+
validated **retrospectively** on existing data with confidence intervals, and reported honestly when absent. It
|
|
43
|
+
chooses informative experiments — including ones that would validate an immune proxy — but it **does not run
|
|
44
|
+
them**; prospective benefit awaits a lab partner (v5.11+).
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""PEN-STACK v3.0 - open infrastructure for genome writing."""
|
|
2
|
-
__version__ = "5.
|
|
2
|
+
__version__ = "5.11.0"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""pen_stack.active — the experiment designer / the "Learn" brain of a self-driving lab (v5.10).
|
|
2
|
+
|
|
3
|
+
Turn "I'm uncertain" into "run THIS experiment next": score each candidate experiment by the information it is
|
|
4
|
+
expected to yield (from the calibrated v5.9 twin), reward experiments that would validate an immune PROXY axis
|
|
5
|
+
(v5.6), assemble a diverse batch, and prove on held-out data — with confidence intervals — that this learns
|
|
6
|
+
faster than random or greedy, reporting honestly when it does not. Lab-optional, falsifiable by construction.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from pen_stack.active.acquire import (
|
|
11
|
+
acquisition_score,
|
|
12
|
+
expected_information_gain,
|
|
13
|
+
immune_voi,
|
|
14
|
+
predictive_entropy,
|
|
15
|
+
)
|
|
16
|
+
from pen_stack.active.design import batch_diversity, select_batch
|
|
17
|
+
from pen_stack.active.validate import retrospective_active_learning
|
|
18
|
+
|
|
19
|
+
__all__ = ["expected_information_gain", "immune_voi", "predictive_entropy", "acquisition_score",
|
|
20
|
+
"select_batch", "batch_diversity", "retrospective_active_learning"]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Acquisition functions for the experiment designer (v5.10, WS-ACQ).
|
|
2
|
+
|
|
3
|
+
Score each candidate experiment by the information it is expected to yield — computed from the calibrated v5.9
|
|
4
|
+
twin's predictive uncertainty (never fabricated). Three signals:
|
|
5
|
+
* expected_information_gain — reducible predictive uncertainty (entropy now - expected posterior entropy),
|
|
6
|
+
* predictive_entropy — the twin's current uncertainty (from its interval width),
|
|
7
|
+
* immune_voi — value of information for VALIDATING an immune PROXY axis (turns proxy -> validated).
|
|
8
|
+
The acquisition is only as good as the v5.9 twin and the v5.6 labels it queries; it chooses informative
|
|
9
|
+
experiments, it does not run them.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import math
|
|
14
|
+
|
|
15
|
+
# a measurement does not resolve uncertainty perfectly: a noise floor on the post-experiment entropy.
|
|
16
|
+
_MEASUREMENT_NOISE_SD = 0.05
|
|
17
|
+
_TWO_PI_E = 2.0 * math.pi * math.e
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _interval_sd(outcome: dict) -> float:
|
|
21
|
+
"""Std-dev implied by the twin's (approx 95%) interval: sd ~ width / (2 * 1.96)."""
|
|
22
|
+
lo, hi = outcome.get("interval", [0.0, 0.0])
|
|
23
|
+
return max(1e-6, (float(hi) - float(lo)) / (2.0 * 1.96))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _gaussian_entropy(sd: float) -> float:
|
|
27
|
+
return 0.5 * math.log(_TWO_PI_E * sd * sd)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def predictive_entropy(outcome: dict) -> float:
|
|
31
|
+
"""Differential entropy of the twin's predictive distribution, from its interval width."""
|
|
32
|
+
return _gaussian_entropy(_interval_sd(outcome))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _expected_posterior_entropy(outcome: dict) -> float:
|
|
36
|
+
"""Entropy expected AFTER running the experiment: the measurement collapses predictive sd toward the
|
|
37
|
+
measurement noise floor (cannot go below it)."""
|
|
38
|
+
post_sd = max(_MEASUREMENT_NOISE_SD, min(_interval_sd(outcome), _MEASUREMENT_NOISE_SD * 2))
|
|
39
|
+
return _gaussian_entropy(post_sd)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def expected_information_gain(candidate: dict, cell_state: str, model_ctx: dict | None = None) -> float:
|
|
43
|
+
"""EIG ~ reducible uncertainty = predictive entropy now - expected posterior entropy. Computed from the
|
|
44
|
+
calibrated twin's predictive distribution; >= 0 (a measurement never increases expected uncertainty)."""
|
|
45
|
+
from pen_stack.twin.outcome import predict_outcome
|
|
46
|
+
o = predict_outcome(candidate, cell_state or candidate.get("cell_state", ""))
|
|
47
|
+
return max(0.0, predictive_entropy(o) - _expected_posterior_entropy(o))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def immune_voi(candidate: dict, cell_state: str = "") -> float:
|
|
51
|
+
"""Value of information for validating an immune PROXY axis (v5.6): an axis still labelled a proxy that this
|
|
52
|
+
experiment would MEASURE is high-VOI (turns proxy -> outcome-validated). Reads the v5.6 validation labels."""
|
|
53
|
+
from pen_stack.twin.outcome import predict_outcome
|
|
54
|
+
prof = predict_outcome(candidate, cell_state or candidate.get("cell_state", "")).get("immune_outcome") or {}
|
|
55
|
+
measures = {str(a).strip().lower() for a in (candidate.get("measures_immune_axes") or [])}
|
|
56
|
+
voi = 0.0
|
|
57
|
+
for axis, rec in prof.get("axes", {}).items():
|
|
58
|
+
label = (rec.get("validation") or "").lower()
|
|
59
|
+
is_proxy = "proxy" in label and "not outcome-validated" in label
|
|
60
|
+
if is_proxy and (not measures or axis.lower() in measures):
|
|
61
|
+
voi += 1.0
|
|
62
|
+
return voi
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def acquisition_score(candidate: dict, cell_state: str, model_ctx: dict | None = None,
|
|
66
|
+
*, w_eig: float = 1.0, w_unc: float = 0.3, w_imm: float = 0.4) -> float:
|
|
67
|
+
"""Weighted acquisition: information gain + raw uncertainty + immune value-of-information. Fully traceable
|
|
68
|
+
to twin quantities + v5.6 labels (no fabricated values); deterministic given the inputs."""
|
|
69
|
+
from pen_stack.twin.outcome import predict_outcome
|
|
70
|
+
o = predict_outcome(candidate, cell_state or candidate.get("cell_state", ""))
|
|
71
|
+
eig = expected_information_gain(candidate, cell_state, model_ctx)
|
|
72
|
+
unc = predictive_entropy(o)
|
|
73
|
+
return w_eig * eig + w_unc * unc + w_imm * immune_voi(candidate, cell_state)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Batch experiment selection with diversity (v5.10, WS-DESIGN).
|
|
2
|
+
|
|
3
|
+
Greedy batch construction: maximise summed acquisition while spreading across the design space, so a batch is a
|
|
4
|
+
DIVERSE set of informative experiments — not k copies of the single most-uncertain point. Each chosen experiment
|
|
5
|
+
carries its expected information gain.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pen_stack.active.acquire import acquisition_score, expected_information_gain
|
|
10
|
+
|
|
11
|
+
# design facets used for the diversity (redundancy) penalty.
|
|
12
|
+
_FACETS = ("writer_family", "delivery_vehicle", "chrom", "edit_intent", "cell_type")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _redundancy(cand: dict, chosen: list[dict]) -> float:
|
|
16
|
+
"""Penalty for similarity to already-chosen experiments: fraction of shared design facets (0..1), summed."""
|
|
17
|
+
if not chosen:
|
|
18
|
+
return 0.0
|
|
19
|
+
pen = 0.0
|
|
20
|
+
for c in chosen:
|
|
21
|
+
shared = sum(1 for f in _FACETS if cand.get(f) is not None and cand.get(f) == c.get(f))
|
|
22
|
+
pen += shared / len(_FACETS)
|
|
23
|
+
return pen
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def batch_diversity(batch: list[dict]) -> float:
|
|
27
|
+
"""Mean pairwise distinctness over the facets (1 = all distinct). Higher = more diverse."""
|
|
28
|
+
if len(batch) < 2:
|
|
29
|
+
return 1.0
|
|
30
|
+
pairs, dist = 0, 0.0
|
|
31
|
+
for i in range(len(batch)):
|
|
32
|
+
for j in range(i + 1, len(batch)):
|
|
33
|
+
shared = sum(1 for f in _FACETS
|
|
34
|
+
if batch[i].get(f) is not None and batch[i].get(f) == batch[j].get(f))
|
|
35
|
+
dist += 1.0 - shared / len(_FACETS)
|
|
36
|
+
pairs += 1
|
|
37
|
+
return dist / pairs if pairs else 1.0
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def select_batch(candidates: list[dict], cell_state: str, model_ctx: dict | None = None,
|
|
41
|
+
*, k: int = 8, w_div: float = 0.5) -> list[dict]:
|
|
42
|
+
"""Greedy diverse batch: at each step pick the candidate maximising acquisition minus a redundancy penalty
|
|
43
|
+
against the already-chosen set. Each returned experiment carries its expected information gain."""
|
|
44
|
+
chosen: list[dict] = []
|
|
45
|
+
remaining = list(candidates)
|
|
46
|
+
while remaining and len(chosen) < k:
|
|
47
|
+
best = max(remaining, key=lambda c: acquisition_score(c, cell_state, model_ctx)
|
|
48
|
+
- w_div * _redundancy(c, chosen))
|
|
49
|
+
chosen.append(best)
|
|
50
|
+
remaining.remove(best)
|
|
51
|
+
return [{**c, "expected_info_gain": expected_information_gain(c, cell_state, model_ctx)} for c in chosen]
|